文章目录
- 基础题记录
- 实践题记录&&与C++比较
- 题目1:
- 题目2:
- 题目3:
基础题记录
编译型语言:
定义:在程序运行之前,通过编译器将源程序编译成机器码(可运行的二进制代码),以后执行这个程序时,就不用再进行编译了。
代表语言:C、C++
解释型语言:
定义:解释型语言的源代码不是直接翻译成机器码,而是先翻译成中间代码,再由解释器对中间代码进行解释运行。在运行的时候才将源程序翻译成机器码,翻译一句,然后执行一句,直至结束。
代表语言:JavaScript、Python
混合型语言:
定义:既然编译型和解释型各有缺点就会有人想到把两种类型整合起来,取其精华去其糟粕,就出现了半编译,半解释型语言。
java就是混合型语言
B:编译:javac 文件名.java 运行:java 文件名
1、 每个编译单元(文件)只能有一个public 类。这么做的意思是,每个编译单元只能有一个公开的接口,而这个接口就由其public 类来表示。
2、 java程序的入口是main方法,所以被定为public的这个类里一定是含有main方法的类,而且该类的名称要和文件名一致,因为虚拟机开始要找main的。(同个源文件有多个公共类,编译器就找不到应该执行的main方法了)
5
goto是的
定义str必须要双引号,双引号,里面一个字符也没事的,但是就是要双引号
java中的float和C语言不一样
字符串和int型是可以相加的,即转成字符串
A:float不能变成long,把n改成int也不行
编译报错:The local variable z may not have been initialized
java中有printf,最终结果是12,x变成了2
实践题记录&&与C++比较
题目1:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
public class TotalArea {
public static void main(String[] args) {
//Map<Integer,Student> mp=new TreeMap<Integer,Student>();
Map<String ,Integer>mp=new HashMap<String,Integer>();
Map<String,Integer>s=new HashMap<String,Integer>();
int n,m,k;
Scanner input=new Scanner(System.in);
n=input.nextInt();
m=input.nextInt();
k=input.nextInt();
String sas=input.nextLine();//第一个坑
for(int i=1;i<=n;++i) {
String str=input.nextLine();
mp.put(str,0);
}
for(int i=1;i<=m;++i) {
String str=input.next();
int score=input.nextInt();
s.put(str,score);
}
for(int i=1;i<=k;++i) {
String str=input.next();
String ss=input.next();
String h=input.next();
if(h.equals("AC")) {
if(s.containsKey(ss)&&mp.containsKey(str)) //第二个坑
mp.put(str, s.get(ss)+mp.get(str));
}
}
Iterator iter=mp.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry entry=(Map.Entry)iter.next();
if(entry.getValue()!=null) //第三个坑
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
第一个坑:如果不加这行代码的话,下面的nextline
会先读取换行符(和C++使用getline
差不多)
第二个坑:如果不加这行代码,编译失败Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.Map.get(Object)" is null
,意思就是可能会是null
第三个坑:如果没有这行代码,此时是没有影响的,因为有if(s.containsKey(ss)&&mp.containsKey(str)
的保证
但是如果那行代码,考虑下面的输入
2 2 4
GabrielPessoa
beza
metebronca 100
geometry 200
beza metebronca AC
ffern numbertheory AC
GabrielPessoa geometry WA
beza geometry AC
输出
GabrielPessoa 0
beza 300
ffern null
但是这是错误的代码,因为题目说输出 N 行, 第 i 行输出第 i个人的名字和对应分数 (名字和分数用空格隔开)。
而现在的代码输出是随机的,下面是错误样例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rRYI3YHC-1690521510537)(https://gitee.com/aure0219/typora-img/raw/master/202307281314921.png)]
本应该先输出2的,但现在先输出了1
所以要加一个数组来记录他们的顺序
下面来看AC代码
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
public class TotalArea {
public static void main(String[] args) {
Map<String ,Integer>mp=new HashMap<String,Integer>();
Map<String,Integer>s=new HashMap<String,Integer>();
int n,m,k;
String []name=new String [1000];
Scanner input=new Scanner(System.in);
n=input.nextInt();
m=input.nextInt();
k=input.nextInt();
String sas=input.nextLine();
for(int i=1;i<=n;++i) {
String str=input.nextLine();
mp.put(str,0);
name[i]=str;
}
for(int i=1;i<=m;++i) {
String str=input.next();
int score=input.nextInt();
s.put(str,score);
}
for(int i=1;i<=k;++i) {
String str=input.next();
String ss=input.next();
String h=input.next();
if(h.equals("AC")) {
if(s.containsKey(ss)&&mp.containsKey(str)) {
mp.put(str, mp.get(str)+s.get(ss));
}
}
}
for(int i=1;i<=n;++i) {
if(mp.get(name[i])!=null) System.out.println(name[i]+" "+mp.get(name[i]));
}
// Iterator iter=mp.entrySet().iterator();
// while(iter.hasNext()) {
// Map.Entry entry=(Map.Entry)iter.next();
// if(entry.getValue()!=null)
// System.out.println(entry.getKey()+" "+entry.getValue());
// }
// }
}
}
通过name数组来存放相对位置,这样输出的时候也就不需要用迭代器了
再来看看用C++写的代码
#include<bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
map<string,int>people;
map<string,int>score;
int main(void) {
int n,m,k,s1;
string s,x,y;
cin>>n>>m>>k;
while(n--){
cin>>s;
people[s]=1;
}
while(m--){
cin>>s>>s1;
score[s]=s1;
}
while(k--){
cin>>s>>x>>y;
if(people[s]&&y=="AC") people[s]=people[s]+score[x];
}
//map<string,int>::iterator it;
//map<int,map<string,int> >::iterator it;
//for(it=people.begin();it!=people.end();it++){
// if(it->second==0) continue;
// cout<<it->first<<" "<<it->second-1<<endl;
//}
for(auto a:people){
if(a.second!=0)
cout<<a.first<<" "<<a.second-1<<endl;
}
return 0;
}
//这个写法没考虑到map会按键进行排序,所以输出的时候没按题中输入顺序输出,所以考虑在map前面在加一个参数来记录输入顺序
和java不一样,c++的map会按键进行排序(c++的map相当于java中的TreeMap
)
#include <bits/stdc++.h>
using namespace std;
map<int,map<string,int> >people;
map<string,int>score;
int main(void){
int n,m,k;
int score1;
string str,str1,str2;
cin>>n>>m>>k;
for(int i=1;i<=n;++i) {
cin>>str;
people[i][str]=1;
}
for(int i=1;i<=m;++i){
cin>>str>>score1;
score[str]=score1;
}
while(k--){
cin>>str>>str1>>str2;
if(str2=="AC"){
for(int i=1;i<=n;++i){
if(people[i][str]>0){
people[i][str]+=score[str1];
break;
}
}
}
}
for(int i=1;i<=n;++i){
for(auto t:people[i]){
if(t.second>0) cout<<t.first<<" "<<t.second-1<<endl;//因为初始化1,所以这里要剪掉1
}
}
return 0;
}
那如果运用这个思路,用java怎么实现呢
public class Student {
public String name;
public int score;
Student(){};
Student(String name,int score){
this.name=name;
this.score=score;
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;
import java.util.TreeSet;
public class TotalArea {
public static void main(String[] args) {
Map<Integer,Student> mp=new TreeMap<Integer,Student>();
Map<String,Integer>s=new HashMap<String,Integer>();
int n,m,k;
Scanner input=new Scanner(System.in);
n=input.nextInt();
m=input.nextInt();
k=input.nextInt();
String sas=input.nextLine();
for(int i=1;i<=n;++i) {
String str=input.nextLine();
mp.put(i,new Student(str,0));
}
for(int i=1;i<=m;++i) {
String str=input.next();
int score=input.nextInt();
s.put(str,score);
}
for(int i=1;i<=k;++i) {
String str=input.next();
String ss=input.next();
String h=input.next();
if(h.equals("AC")) {
Iterator iter=mp.entrySet().iterator();
while(iter.hasNext()) {
Map.Entry entry=(Map.Entry)iter.next();
if(entry.getValue()!=null) //此时要返回下标,然后进行操作,但现在还未能实现
}
}
}
}
}
通过对比,我觉得我在实现类似map类有关操作时,还是C++的STL用的比较熟练,代码量也相对于Java来说较少。
题目2:
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
public class TotalArea {
public static void main(String[] args) {
Set<Point> p=new HashSet<Point>();
Scanner in=new Scanner(System.in);
int n=in.nextInt();
final int N=600;
int [][]ch=new int [N][2];
for(int i=1;i<=n;++i) {
ch[i][0]=in.nextInt();
ch[i][1]=in.nextInt();
}
for(int i=1;i<=n;++i) {
for(int j=1;j<=n;++j) {
if(i!=j) {
int a=ch[i][0]-ch[j][0];
int b=ch[i][1]-ch[j][1];
p.add(new Point(a/gcd(a,b),b/gcd(a,b)));
}
}
}
System.out.println(p.size());
}
static int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
}
class Point{
private int x;
private int y;
Point(){};
public Point(int x,int y){
this.x=x;
this.y=y;
}
}
下面来看C++AC代码
#include <bits/stdc++.h>
#include <iostream>
#include <algorithm>
#include <set>
using namespace std;
set<pair<int,int> >mp;//set里面放pair
//map<int,vector<int> >mp;
int ch[510][2];
int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
int main(void) {
int n;
cin>>n;
for(int i=1;i<=n;++i){
cin>>ch[i][0]>>ch[i][1];
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(i!=j){
int x=ch[i][0]-ch[j][0];
int y=ch[i][1]-ch[j][1];
// mp.insert(pair<int,int>(x/gcd(x,y),y/gcd(x,y)));
//mp.insert(make_pair(x/gcd(x,y),y/gcd(x,y)));
mp.insert({x/gcd(x,y),y/gcd(x,y)});//这几种写法都可以的
}
}
}
cout<<2*mp.size();
return 0;
}
为什么用c++写最后的size要乘2呢,而java直接就是size呢,按代码分析理应是两个都需要*2的,因为一正一负,而存入set中的都是正的
//下面是java的
输入:
3
1 1
4 5
1 4
输出:
3 1
3 4
0 1
3 4
3 1
0 1
6
//发现此时的set并没有去重
//下面是C++的
输入:
3
1 1
4 5
1 4
输出:
0 1
3 1
3 4
6
注:在java中set去重是对象去重, 对象内容一样,但对象引用不一样,无法去重
package javafx.geometry;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;
public class TotalArea {
public static void main(String[] args) {
Set<Point> p=new HashSet<Point>();
Scanner in=new Scanner(System.in);
int n=in.nextInt();
final int N=600;
int [][]ch=new int [N][2];
for(int i=1;i<=n;++i) {
ch[i][0]=in.nextInt();
ch[i][1]=in.nextInt();
}
for(int i=1;i<=n;++i) {
for(int j=1;j<=n;++j) {
if(i!=j) {
int a=ch[i][0]-ch[j][0];
int b=ch[i][1]-ch[j][1];
Point c=new Point(a/gcd(a,b),b/gcd(a,b));
p.add(c);
}
}
}
Iterator<Point>it=p.iterator();
while(it.hasNext()) {
Point c=(Point)it.next();
System.out.println(c.getX()+" "+c.getY());
}
System.out.println(p.size());
}
static int gcd(int x,int y){
return y==0?x:gcd(y,x%y);
}
}
class Point{
private Integer x;
private Integer y;
Point(){};
public Point(Integer x,Integer y){
this.x=x;
this.y=y;
}
public Integer getX() {
return x;
}
public Integer getY() {
return y;
}
@Override
public boolean equals(Object obj) {
// System.out.println("调用equals方法,当前的hashCode为:"+hashCode());
/** 对象是 null 直接返回 false **/
if (obj == null) {
return false;
}
/** 对象是当前对象,直接返回 true **/
if (this == obj) {
return true;
}
/** 判断对象类型是否是User **/
if (obj instanceof Point) ;
Point vo=(Point) obj;
/** 比较每个属性的值一致时才返回true **/
/** 有几个对象就要比较几个属性 **/
if (vo.x.equals(this.x) && vo.y.equals(this.y)) {
return true;
}
return false;
}
/**
* 重写hashcode方法,返回的hashCode一样才再去比较每个属性的值
*/
@Override
public int hashCode() {
return this.getX().hashCode() * this.getY().hashCode();
}
}
这样,才实现了去重功能,上面如果写int
编译过不了的(Cannot invoke equals(int) on the primitive type int
Cannot invoke hashCode() on the primitive type int
),
其中equals
改成==就行了,但是hashCode
怎么改。
那么写成Integer
就不会报错了
输入
3
1 1
4 5
1 4
输出:
0 1
3 1
3 4
3
题目3:
Java代码
import java.util.LinkedList;
import java.util.Scanner;
public class TestCircle {
public static void main(String[] args) {
LinkedList<Integer> l=new LinkedList<Integer>();
Scanner input=new Scanner(System.in);
int t=input.nextInt();
for(int i=1;i<=t;++i) {
String str=input.next();
if(str.equals("insert")) {
int a=input.nextInt();
int b=input.nextInt();
l.add(a,b);
}
else if(str.equals("delete")) {
int a=input.nextInt();
l.remove(a-1);
}
else if(str.equals("query")) {
int a=input.nextInt();
System.out.println(l.get(a-1));
}
}
}
}
当时复制输入数据的时候,发现最后一个query后的值不会输出,debug了好久迟迟发现不了什么问题,以为是代码出现了问题,最后发现还要按一下回车才行。。。。
C++ 代码
#include <bits/stdc++.h>
#include <vector>
using namespace std;
vector<int>G;
int main(void){
int n,x,y;
cin>>n;
string str;
while(n--){
cin>>str;
if(str=="insert"){//string类型支持直接等于比较
cin>>x>>y;
G.insert(G.begin()+x,y);
}
else if(str=="query"){
cin>>x;
cout<<G[x-1]<<endl;
}
else if(str=="delete"){
cin>>x;
G.erase(G.begin()+x-1);
}
}
return 0;
}
这题的话,两种语言写法差不多,代码量也差不多