第5周-数组
- 数组是长度固定的数据结构
- 一个数组里的数据类型必须相同
- 数组一旦创建,不能改变长度。
//用户输入一系列整数,存入数组,当输入-1时结束
int x;
int cnt = 0;
int[] numbers = new int[100]; //这里必须指定数组的长度。一但用户输入数据超过100,程序会崩溃。可以使用变量。
x = in,nextInt();
while (x != -1) {
numbers[cnt] = x;
cnt++;
x = in,nextInt();
}
numbers.length返回的是数组的长度。
创建的数组变量numbers是数组的管理者,它管理着new int[100]这个数组,但并不拥有。
下面来新建另外一个数组管理者otherNumbers:
int[] otherNumbers = numbers;
otherNumber[0] = 10; //新的管理者对数组进行赋值修改
System.out,print(numbers[0]); -->这时,numbers[0]的值也是10,因为这两个数组变量同时管理着同一个数组。
new创建的数组会得到默认的0值。
下面这个例子,让用户随机输入0-9若干的数字,输入-1时结束输入,统计每个数字出现的次数:
int[] numbers = new int[10]; //以输入的0-9数字作为下标。
int x;
x = in.nextInt();
while (x != -1) {
if (x>=0 && x<=9) {
numbers[x]++; //在x位置的初始值为0,用户每输入一个相同的数,则加1。
}
x = in.nextInt(); //在循环中再次读入用户输入。
}
for (int i=0; i
构建素数的计算机思维:素数是只能被1和自身整除的数,如果我们要判断一个数是不是素数
- 方法1:用这个数n除以从2-->n-1的数,余数都不为0,则n是素数
int n = in.nextInt();
boolean isPrime = true;
if (n==1) { isPrime = false; }
for (int=2; i
- 方法2:可以把被除数中的偶数去掉,这样循环次数减半
if (n==1 || n%2 == 0 && n!=2) {
isPrime = false;
}
else {
for (int i =3; i
- 方法3:循环甚至不用到n-1,只用到n的平方根(sqrt(n))就可以了
for (int i=3; i
for-each循环
用来访问数组中每一个元素,但不能修改,同时返回值也没有下标。
for (<类型> <变量名>: <数组>) {
...
}
构造前50个素数表:
int[] primes = new int[50];
primes[0] = 2;
int cnt = 1;
MAIN-LOOP:
for (int x=3; cnt
如果要构造n以内的素数表(原理-所有素数的倍数都不是素数
):
- 令x=2
- 将2x、3x、4x直至ax
- 令x为下一个没有被标记为非素数的数,重复2;直至所有的数都已经尝试完毕
boolean[] isPrime = new boolean[100]; //创建一个boolean数组,里面每一个位置的值只有true和false
for (int i =2; i
二维数组
int[][] a = new int[3][5];
通常理解为a是一个3行5列的矩阵
a[0][0] | a[0][1] | a[0][2] | a[0][3] | a[0][4] |
---|---|---|---|---|
a[1][0] | a[1][1] | a[1][2] | a[1][3] | a[1][4] |
a[2][0] | a[2][1] | a[2][2] | a[2][3] | a[2][4] |
- 二维数组的遍历
for (i=0; i<3; i++) {
for (j=0; j<5; j++) {
a[i][j] = i*j;
}
}
第5周编程作业-多项式加法
一个多项式可以表达为x的各次幂与系数乘积的和,比如:
2x6+3x5+12x3+6x+20
现在,你的程序要读入两个多项式,然后输出这两个多项式的和,也就是把对应的幂上的系数相加然后输出。
程序要处理的幂最大为100
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int pow,num;
//声明一个数组poly,长度101,可处理100次幂
int[] poly = new int [101];
int cnt1=0;
//读入用户输入,在读到两次pow=0时结束
for(;cnt1<2;)
{
pow=in.nextInt();
num=in.nextInt();
//在poly数组第[pow]的位置,存入num,幂次就是数组的下标
poly[pow]+=num;
if(pow==0)
{
cnt1++;
}
}
int cnt2=0;
//反向遍历数组
for(int i=poly.length-1;i>=0;i--)
{
//条件:num != 0
if(poly[i]!=0)
{
//条件:首位为负数,cnt2==0判断首次
if(cnt2==0&&poly[i]<0)
{
System.out.print("-");
}
if(cnt2!=0)
{
if(poly[i]>0) System.out.print("+");
if(poly[i]<0) System.out.print("-");
}
//条件:0次幂
if(i==0)
{
System.out.print(Math.abs(poly[i]));
}
//条件:i=1时1次幂 或者 系数为1时
else if(i==1||Math.abs(poly[i])==1)
{
if(i==1&&Math.abs(poly[i])==1) System.out.print("x");
if(i==1&&Math.abs(poly[i])!=1) System.out.print(Math.abs(poly[i])+"x");
if(i!=1&&Math.abs(poly[i])==1) System.out.print("x"+i);
}
//条件:i>1 次幂
else
{
System.out.print(Math.abs(poly[i])+"x"+i);
}
cnt2++;
}
//条件:系数num == 0,不输出
else {
if(i==0) System.out.print(poly[i]);
continue;
}
}
}
}
第6周-使用对象
- 字符类型
单个字符是一种特殊的类型:char
java使用Unicode来表示字符,可以表达包括汉字在内的多种文字
1.字符计算:每个字符对应Unicode码表中的数字
char c = 'A';
c++;
System.out.println(c); -->输出得到'B'
int i = 'Z'-'A';
System.out.println(i); -->输出得到'Z'和'A'在表中的距离
2.字符可以比较大小,依据是它们在Unicode表中的编号:'Z'<'a'
3.逃逸字符:用来表达无法打印出来的控制字符或特殊字符,由一个反斜杠""开头,组合另一个字符
字符 | 意义 | 字符 | 意义 |
---|---|---|---|
\b | 回退一格 | \" | 双引号 |
\t | 到下一个表格位 | \' | 单引号 |
\n | 换行 | \\ | 反斜杠本身 |
\r | 回车 |
- 包裹类型
每种基础类型都有对应的包裹类型
基础类型 | 包裹类型 |
---|---|
boolean | Boolean |
char | Charater |
int | Integer |
double | Double |
每个包裹类型有特殊的函数方法,可以帮助我们做很多事情
函数方法 | 说明 |
---|---|
Math.abs() | 绝对值 |
Math.pow(n, x) | n的x次方(浮点数) |
Math.random() | 0-1之间的随机数 |
Math.round() | 四舍五入取整 |
- 字符串
String s = new String("a string");
创建了一个String的对象
用"a string"初始化这个对象
创建管理这个对象的变量s
让s管理这个对象
in.next();
读入一个单词,单词的标志是空格
in.nextLine();
读入一整行
字符串操作--不能修改字符串本身,而是在原基础上创建了新的字符串
函数方法 | 说明 |
---|---|
s.equals("string") | 比较内容是否相同 |
s1.compareTo(s2) | 两个字符串比较大小,相等是0 |
s1.compareToIgnoreCase(s2) | 忽略大小写比较大小 |
s.length() | 获取字符串长度 |
s.charAt(index) | 返回在index 上的单个字符 |
s.substring(n) | 获取n号位到结尾的全部内容 |
s.substring(a,b) | 获取a号位到b号位之前的全部内容 |
s.indexOf(c) / s.lastIndexOf(c) | 得到c字符所在的位置,-1表示不存在 / 从末尾开始找 |
s.indexOf(c,n) / s.lastIndexOf(c,n) | 从n号位置开始找c字符所在的位置,-1表示不存在 / 从末尾开始找 |
s.startsWith(t) | 是否以t开头 |
s.endsWith(t) | 是否以t结尾 |
s.trim() | 去掉字符串两端的空格 |
s.replace(c1,c2) | 用c1替换c2 |
s.toLowerCase() | 转换小写 |
s.toUpperCase() | 转换大写 |
第6周编程作业-单词长度
你的程序要读入一行文本,其中以空格分隔为若干个单词,以‘.’结束。
你要输出这行文本中每个单词的长度。
这里的单词与语言无关,可以包括各种符号,比如“it's”算一个单词,长度为4。
注意,行中可能出现连续的空格。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String s = new String(in.nextLine());
int loc = s.indexOf(" ");
int cnt = 1;
if (s.lastIndexOf(".")==-1) {
System.out.println("format error");
s = in.nextLine();
}
if (loc == -1 && s.length()!=1)
{
System.out.println(s.length()-1);
}
else if (s.length()!=1)
{
while (s.indexOf(" ",loc+1)!=-1)
{
loc = s.indexOf(" ",loc+1);
cnt++;
}
int[] whiteSpace = new int[cnt];
whiteSpace[0] = s.indexOf(" ");
loc = s.indexOf(" ");
cnt = 1;
while (s.indexOf(" ",loc+1)!=-1)
{
loc = s.indexOf(" ",loc+1);
whiteSpace[cnt] = loc;
cnt++;
}
System.out.print(whiteSpace[0]+" ");
for (int i=1; i
第6周编程作业-GPS数据处理
NMEA-0183协议是为了在不同的GPS(全球定位系统)导航设备中建立统一的BTCM(海事无线电技术委员会)标准,
由美国国家海洋电子协会(NMEA-The National Marine Electronics Associa-tion)制定的一套通讯协议。
GPS接收机根据NMEA-0183协议的标准规范,将位置、速度等信息通过串口传送到PC机、PDA等设备。
NMEA-0183协议是GPS接收机应当遵守的标准协议,也是目前GPS接收机上使用最广泛的协议,
大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。
NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等。
其中$GPRMC语句的格式如下:
$GPRMC,024813.640,A,3158.4608,N,11848.3737,E,10.05,324.27,150706,,,A*50
这里整条语句是一个文本行,行中以逗号“,”隔开各个字段,每个字段的大小(长度)不一,
这里的示例只是一种可能,并不能认为字段的大小就如上述例句一样。
字段0:$GPRMC,语句ID,表明该语句为Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐最小定位信息
字段1:UTC时间,hhmmss.sss格式
字段2:状态,A=定位,V=未定位
字段3:纬度ddmm.mmmm,度分格式(前导位数不足则补0)
字段4:纬度N(北纬)或S(南纬)
字段5:经度dddmm.mmmm,度分格式(前导位数不足则补0)
字段6:经度E(东经)或W(西经)
字段7:速度,节,Knots
字段8:方位角,度
字段9:UTC日期,DDMMYY格式
字段10:磁偏角,(000 - 180)度(前导位数不足则补0)
字段11:磁偏角方向,E=东W=西
字段16:校验值
这里,“*”为校验和识别符,其后面的两位数为校验和,代表了“$”和“*”之间所有字符(不包括这两个字符)的异或值的十六进制值。
上面这条例句的校验和是十六进制的50,也就是十进制的80。
提示:^运算符的作用是异或。将$和*之间所有的字符做^运算(第一个字符和第二个字符异或,结果再和第三个字符异或,依此类推)之后的值对65536取余后的结果,
应该和*后面的两个十六进制数字的值相等,否则的话说明这条语句在传输中发生了错误。
注意这个十六进制值中是会出现A-F的大写字母的。
另外,如果你需要的话,可以用Integer.parseInt(s)从String变量s中得到其所表达的整数数字;
而Integer.parseInt(s, 16)从String变量s中得到其所表达的十六进制数字
现在,你的程序要读入一系列GPS输出,其中包含$GPRMC,也包含其他语句。
在数据的最后,有一行单独的
END
表示数据的结束。
你的程序要从中找出$GPRMC语句,计算校验和,找出其中校验正确,并且字段2表示已定位的语句,
从中计算出时间,换算成北京时间。一次数据中会包含多条$GPRMC语句,以最后一条语句得到的北京时间作为结果输出。
你的程序一定会读到一条有效的$GPRMC语句。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[] GPS = new String[100];
String time = null;
int cnt=0;
//将用户输入的多条语句,遍历存到数组,cnt变量记录输入了多少条
for (int i=0;i<100;i++) {
GPS[i] = in.nextLine();
if (GPS[i].equals("END")) {
break;
}
cnt++;
}
for (int i=0; i
第7周-函数
- java函数必须定义在类的内部,成为类的成员
<返回类型> <方法名称>(<参数表>) {
<方法体>
}
- 函数可以返回基本数据类型、对象或者void(表示这个函数不返回任何值)。
- 在这个阶段,要在所有函数的返回类型前面加上关键字"static"。
- static表示这个函数属于这个类,不属于任何对象,可以直接从main()函数中调用。
//计算a到b的所有数的和
public static void sum(int a; int b) {
int i;
int sum = 0;
for (i=a; i<=b; i++) {
sum += i;
}
return sum;
}
- 函数是一块代码,接收零个或多个参数,做一件事,并返回零个或一个值。
- return停止函数的执行,并返回一个值。
- 在调用函数的时候,永远只能传值给函数。
public static void main(String[] args) {
int a = 5;
int b = 10;
sum(a,b);
System.out.println(a+"到"+b+"的和是"+sum);
}
第7周编程作业-分解质因数
每个非素数(合数)都可以写成几个素数(也可称为质数)相乘的形式,
这几个素数就都叫做这个合数的质因数。
比如,6可以被分解为2x3,而24可以被分解为2x2x2x3。
现在,你的程序要读入一个[2,100000]范围内的整数,然后输出它的质因数分解式;
当读到的就是素数时,输出它本身。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] prime = new int[100000];
int comNum = in.nextInt();
int cnt1=0;
//判断输入:
if (comNum<2 || comNum>100000) {
System.out.print("format error, please input an integer at [2,100000]:");
comNum = in.nextInt();
}
//判断输入的comNum是否素数,是则直接输出:
int isPrime=1;
for (int i=2; i
第7周编程作业-完数
一个正整数的因子是所有可以整除它的正整数。
而一个数如果恰好等于除它本身外的因子之和,这个数就称为完数。
例如6=1+2+3(6的因子是1,2,3)。
现在,你要写一个程序,读入两个正整数n和m(1<=n
import java.util.Scanner;
public class Main {
//定义factor()函数,输入一个数,判断是否是完数:
public static boolean factor(int s) {
int sum=0;
for (int i=1; i=1) {
for (int i=0; i