个位数统计
题目:
思路:
看到题没多想,思路很明确,以string类型接收键盘输入的数字。然后将该变量转成一个整形数组。再遍历该数组,数每一个数出现了几次。将数字和出现次数以键值对的形式存入treemap。在数数之前先判断键值中是否已经有这个数了,如果有,就不用数了。
知识点for me:
1、在初始化数组不确定数组长度时,只能用ArrayList,可以通过add()方法添加元素。可以添加完成后,通过toArray()把它转成数组,也可以直接利用get()取出元素。
2、map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。其中这四者的区别如下(简单介绍):
HashMap:我们最常用的Map,它根据key的HashCode 值来存储数据,根据key可以直接获取它的Value,同时它具有很快的访问速度。HashMap最多只允许一条记录的key值为Null(多条会覆盖);允许多条记录的Value为 Null。非同步的。
TreeMap: 能够把它保存的记录根据key排序,默认是按升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。TreeMap不允许key的值为null。非同步的。
Hashtable: 与 HashMap类似,不同的是:key和value的值均不允许为null;它支持线程的同步,即任一时刻只有一个线程能写Hashtable,因此也导致了Hashtale在写入时会比较慢。
LinkedHashMap: 保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.在遍历的时候会比HashMap慢。key和value均允许为空,非同步的。
这道题使用TreeMap可以直接省去排序的步骤。
3、使用迭代器遍历map:
Iterator it=tm.keySet().iterator();
Object k;
while(it.hasNext())
{
k=it.next();
System.out.println(k+":"+tm.get(k));
}
在这里我一开始犯了一个错,直接System.out.println(it.next()+":"+tm.get(it.next()))了,后果就是next()一次就再往后一个元素,输出都错位了,自行想象。
4、char转成int,这次我是这么做的:Integer.parseInt(String.valueOf(s.charAt(i)))。
5、再就是,用debug调试程序真的很清楚很快,以后还要多练习。
上代码:
import java.io.*; import java.util.*; public class Main { public static void main(String[] args) { // TODO Auto-generated method stub InputStreamReader isr=new InputStreamReader(System.in); BufferedReader br=new BufferedReader(isr); String s=null; try { s=br.readLine(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } List<Integer> list=new ArrayList();//将字符串变换成整形数组 int length=s.length(); int i,j,sum=0; for(i=0;i<length;i++) { list.add(Integer.parseInt(String.valueOf(s.charAt(i)))); } TreeMap tm=new TreeMap();//存储所有数字和相应数量 for(i=0;i<length;i++) { if(tm.containsKey(list.get(i))!=true) { for(j=0;j<length;j++) { if(list.get(j)==list.get(i)) sum++; tm.put(list.get(i), sum); } } sum=0; } Iterator it=tm.keySet().iterator(); Object k; while(it.hasNext()) { k=it.next(); System.out.println(k+":"+tm.get(k)); } } }
提交成功之后,在网上观摩了一下别人写的。比我这老实孩子没动多大脑筋老老实实按第一想法写的确实要巧妙很多。也放这里学习一下。
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); //用于存储输入的数字 String string = in.next(); in.close(); int[] count = new int[10]; //遍历每个数字,并增加对应数字出现的次数 for (int i = 0; i < string.length(); i++) { char c = string.charAt(i); count[c-'0']++; } for (int i = 0; i < count.length; i++) { if (count[i] != 0) { System.out.println(i+":"+count[i]); } } } }
这个程序的思想就是定义一个十位的数组(因为个位数只有十种:0123456789),初始值都为零,遍历每个数字,给以这个数字为下标的元素值加一,也是一种巧妙的“键值对”吧,还比map简单多了,排序也省了。最后只输出元素不为0的相应下标和元素即可。可真是个小机灵鬼,学习了。
然后,他们把char转成int是直接通过c-'0',也就是程序中的c和‘0’的ASCII的差值。如果直接用(int)强制类型转换的话,得到的会是那个char的ASCII值。我那个做法过于耿直。
当时用Java好年轻,还是C++好,不想解释了,上代码:
上代码:
#include <iostream> #include <cstdio> using namespace std; int main() { string s; int arr[10]={0}; cin>>s; for(int i=0;i<s.length();i++) { arr[s[i]-'0']++; } for(int i;i<10;i++) { if(arr[i]!=0) { cout<<i<<":"<<arr[i]<<endl; } } }