A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 无此姓名 中级黑马   /  2014-4-1 22:57  /  19201 人查看  /  32 人回复  /   2 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 无此姓名 于 2014-4-1 23:00 编辑

这是黑马基础测试里的一个题目,感觉有点意思,和大家讨论一下。
需求数组去重复,例如: 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}。
前提:在网上看到有其他办法,但目前我们课程刚进行到String类,很多知识都没学到,想到用“标志位计算元素个数”的办法。
问题:就目前我的知识水平(刚刚学完String类)不知道大家有什么好的解决办法没有。
我的代码如下

  1. package com.itheima;

  2. import java.util.Arrays;

  3. public class Test8 {

  4.         /**
  5.          *需求:数组去重复,例如: 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}
  6.          * @param args
  7.          */
  8.         public static void main(String[] args) {
  9.                 int arr[]={4,2,4,6,1,2,4,7,8};
  10.                 System.out.println(Arrays.toString(repeat(arr)));        //将去重后数组打印出来
  11.         }
  12.         
  13.         /*定义方法实现去重。
  14.          * 思路:
  15.          *                 1、先确定去重后数组元素的个数count,定义一个boolean类型数组来给重复的元素做标志;
  16.          *                 2、定义元素个数为count的新数组arrNew,将所有不重复的元素存入数组中。
  17.          *                 3、将arrNew返回。
  18.          * */
  19.         
  20.         public static int[] repeat(int [] arr){
  21.                 boolean flag[] = new boolean[arr.length];//定义一个和目标数组长度一样的boolean类型,此数组用作标示,用于获取不重复元素的个数的标志位
  22.                 for (int i = 0; i < flag.length; i++) {//遍历数组,查找重复的元素。循环结束后,重复的元素对应的标志位置都为true。
  23.                         if (flag[i]) //如果这个元素对应的标志位已被置为true,则返回循环继续检查下一个元素。
  24.                                         continue;
  25.                         for (int j = i+1; j < flag.length; j++) {    //后边元素和此位置上的元素比较,
  26.                                 if (arr[j]==arr[i]) {     //如果后边元素和前边元素相同,
  27.                                         flag [j]=true;   //则此重复元素对应的标志位置为true
  28.                                 }
  29.                         }
  30.                 }
  31.                
  32.                 int count=0;    //计数器,记录不重复元素的个数
  33.                 for (int i = 0; i < flag.length; i++) {    //算出不重复元素的个数,记为count,
  34.                         if (!flag[i]) {      //标志位依然为false的对应元素即为不重复的元素
  35.                                 count++;
  36.                         }
  37.                 }
  38.                
  39.                 int index=0;
  40.                 int [] arrNew = new int [count];        //定义新数组,元素个数为count。
  41.                 for (int i = 0; i < arr.length; i++) {        //将所有不重复的元素存入新数组中
  42.                         if (!flag[i]) {
  43.                                 arrNew[index++]=arr[i];
  44.                         }
  45.                 }
  46.                
  47.                 return arrNew;        //返回数组
  48.         }
  49. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
朱神必 + 1

查看全部评分

32 个回复

正序浏览

你这个思想挺好的,但是如果数组里面本来就有-1的话,-1这个值也会被跳过,结果就会有误。
回复 使用道具 举报
搞了好一会。没搞出来,
回复 使用道具 举报
2楼写的比较好                  
回复 使用道具 举报
编立数组然后去掉相同的行吗?
回复 使用道具 举报
Saner 发表于 2014-4-2 12:32
思想大概就是把数组放到set里面(set的值不会重复)就可以去重了
                  Integer[] arr = {4,2, ...

你这样,输出的结果并不是{4,2,6,1,7,8}.而是{1,2,4,6,7,8}
回复 使用道具 举报
不错,都挺厉害啊
回复 使用道具 举报
1453149997 发表于 2014-4-2 12:14
下面的内容请不要抄袭,这是我在黑马基础测试题里的解法:

还行吧,只是感觉你这样有生成数组吗?
回复 使用道具 举报
风逝 中级黑马 2014-11-18 15:57:26
26#
  1. import java.util.List;
  2. import java.util.concurrent.CopyOnWriteArrayList;

  3. /**
  4. * 创建时间:2014-11-18 下午3:26:35
  5. *
  6. * @author zhangtianyou
  7. * @version 2.2
  8. */

  9. public class ArrayRemoveRepeat {

  10.         /**
  11.          * @param args
  12.          */
  13.         public static void main(String[] args) {
  14.                 // 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}。
  15.                 System.out.println("之前的数组");
  16.                 Integer[] src = { 4, 2, 4, 6, 1, 2, 4, 7, 8 };
  17.                 for (Integer k : src) {
  18.                         System.out.print(k + ",");
  19.                 }

  20.                 List<Integer> list = new CopyOnWriteArrayList<Integer>(src);


  21.                 int i = 0;
  22.                 while (i < list.size() - 1) {
  23.                        
  24.                         int j = i+1;
  25.                         while (j < list.size()) {
  26.                                 if (list.get(i) == list.get(j)) {
  27.                                         list.remove(j);
  28.                                         j--;
  29.                                 }
  30.                                 j++;
  31.                         }
  32.                        

  33.                         i++;
  34.                 }

  35.                 src = list.toArray(new Integer[list.size()]);
  36.                 System.out.println("\n之后的数组");
  37.                 for (Integer k : src) {
  38.                         System.out.print(k + ",");
  39.                 }
  40.         }
  41. }
复制代码
回复 使用道具 举报
挺好的不错。思维清晰
回复 使用道具 举报
王春涛 发表于 2014-6-26 10:24
for(Integer i : arr)   这是什么用法?新手没见过

for ...each 循环,就是遍历arr数组中的每一个数
回复 使用道具 举报
贴一下我写的吧,只是用到数组知识
package com.itheima;
//*7、 数组去重复,例如: 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}
思路:
        1.新建一个长度和原数组长度相同的空数组,
        2.依次取出原数组中的数和新数组的每个数做比较,如果有就下一个数做比较,没有就把数放到新数组
                并且定义一个变量记录不重复数字的个数
        3.遍历完得到的新数组中为不重复数组,但是后面会有空的位置,再新建一个数组,长度为不重复数字的个数,将第二个数组复制到新数组.
public class Test7 {
        public static void main(String[] args) {
                int[]arr1={1,2,3,4,5,6,7,8,9,9};//原始数组arr1
                int[]arr2=new int[arr1.length];//新建数组arr2用来接收不重复数字,长度和原数组相同,因为可能原数组全部都不重复.
                int count=1;//记录不重复的数字个数
                arr2[0]=arr1[0];//将第一个数放进新数组
                loop2:
                for(int i=0;i<arr1.length;i++){//取出arr1 的每个数
                        for(int j=0;j<count;j++){
                                if(arr2[j]!=arr1[i]){//如果arr2 中没有arr1 取出的数字,把这个数字放进arr2,计数器加一
                                        if(j==count-1){
                                                arr2[count]=arr1[i];
                                                count++;
                                        }
                                        continue ;//放完继续下一个arr1中的数
                                }else{
                                        continue loop2;//有重复的,直接再来一轮
                                }
                        }
                }
                int arr3[]=new int[count];//因为arr2 后面有空位,去掉空位复制新数组,新数组就是不重复的
                for(int i=0;i<count;i++){
                        arr3[i]=arr2[i];
                }
                print(arr1);//
                System.out.println();
                print(arr3);
        }
        public static void print(int arr[]){//打印数组函数
                for(int i=0;i<arr.length;i++){
                        System.out.print(arr[i]+"\t");
                }
        }

}
回复 使用道具 举报
本帖最后由 孤鸢 于 2014-8-23 00:19 编辑

我有个没有用集合的方法,在考试审核通过了发的,加技术分的各种可能都不放过0.0  @加分  大神
  1. public class Test8
  2. {
  3.         public static void main(String[] args)
  4.         {
  5.                 int[] arr = {4,2,4,6,1,2,4,7,8};
  6.                 int len = arr.length;
  7.                 System.out.println("原数组:");
  8.                 printArray(arr,len);
  9.                
  10.                 /*
  11.                  *思路:每遇到重复的元素,就将其后面的元素向前移一位,然后将数组长度减1。
  12.                  *                这样增加了系统的开销,因为移动次数多了,但是思路很好理解,而且结果没有打乱原数的顺序
  13.                  */
  14.                 for(int i=0; i<len-1; i++)
  15.                 {
  16.                         int key = arr[i];
  17.                         for(int j=i+1; j<len; j++)
  18.                         {
  19.                                 if(arr[j] == key)
  20.                                 {
  21.                                         for(int k=j; k<len-1; k++)
  22.                                         {
  23.                                                 arr[k] = arr[k+1];                                                
  24.                                         }
  25.                                         len = len-1;
  26.                                 }
  27.                         }
  28.                 }
  29.                 System.out.println("去重复后数组:");
  30.                 printArray(arr,len);
  31.                

  32.                
  33.         }
  34.         //打印数组
  35.         public static void printArray(int[] a, int len)
  36.         {               
  37.                 for(int i=0; i<len; i++)
  38.                         System.out.print(a[i]+" ");      //这儿曾将双引号写成了单引号,死活打印不出正确数组,坑死了^_^
  39.                 System.out.println();
  40.         }
  41. }
复制代码
回复 使用道具 举报
我也有这道题学习了
回复 使用道具 举报
  1. package com.itheima;

  2. import java.util.ArrayList;
  3. import java.util.List;

  4. @SuppressWarnings({ "rawtypes", "unchecked" })
  5. public class Test7 {
  6.         /**
  7.          * 7、 数组去重复,例如: 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}
  8.          */
  9.         public static void main(String[] args) {
  10.         int[] arr = { 4, 2, 4, 6, 1, 2, 4, 7, 8 };
  11.         //创建对象
  12.         List data = new ArrayList();
  13.         //增强for
  14.         for (int num : arr) {
  15.             if (!data.contains(num)) {
  16.                 data.add(num);
  17.             }
  18.         }
  19.         //打印数组
  20.         System.out.println(data);
  21.     }
  22. }
复制代码
回复 使用道具 举报 2 0
学习学习!
回复 使用道具 举报
Saner 发表于 2014-4-2 12:32
思想大概就是把数组放到set里面(set的值不会重复)就可以去重了
                  Integer[] arr = {4,2, ...

for(Integer i : arr)   这是什么用法?新手没见过
回复 使用道具 举报
无此姓名 发表于 2014-4-5 10:03
好吧,你赢了,这题确实没什么实际用处。但是限定范围就是为了搞一搞奥数题嘛。 ...

你说的有道理,我最开始接触这题的时候,学习进度还不如你,我写了篇技术博客,引用了你的代码,地址:
http://blog.csdn.net/u013938806/article/details/22985985
回复 使用道具 举报
lwy0319 发表于 2014-4-3 02:54
好吧。。。满足你。。不过感觉没必要太较真。。毕竟后面很快就会学到动态数组了。马上你就是不用跟小学 ...

好吧,你赢了,这题确实没什么实际用处。但是限定范围就是为了搞一搞奥数题嘛。
回复 使用道具 举报
  1. public class Test{
  2.         public static void main(String[] args) {
  3.                 int oldA[]={4,2,4,6,1,2,4,7,8,0,0,-1,-1,-2,-2,-3};//初始化原始数组
  4.                 int x=0;//初始化新的数组长度
  5.                 int y=0;//初始化新数组的脚标
  6.                 int m=0;
  7.                 int n=0;
  8.                 int nonexistent=0;
  9.                 int a=0;
  10.                 while(a<oldA.length){
  11.                         for(int i=0;i<oldA.length;i++){
  12.                                 if(oldA[i]==nonexistent)
  13.                                         nonexistent--;
  14.                         }
  15.                         a++;
  16.                 }
  17.                         for(int i=1;i<oldA.length;i++){//嵌套循环给与数组索引编号靠后的项数相同的项赋值为nonexistent
  18.                                 for(int j=0;j<i;j++){
  19.                                         if(oldA[i]==oldA[j]){
  20.                                                 oldA[i]=nonexistent;
  21.                                         }
  22.                                         }
  23.                                 }
  24.                         for(int i=0;i<oldA.length;i++){//判断原始数组变更后的0项的个数
  25.                                 if(oldA[i]!=nonexistent){            //并从新数组长度的初值减去
  26.                                         x++;
  27.                                 }
  28.                         }
  29.                 //}
  30.                
  31.                 int newA[]=new int[x];//初始化新数组,类型,长度
  32.                 for(int i=0;i<oldA.length;i++){
  33.                         if(oldA[i]!=nonexistent){//将原始数组中的非零项加入新数组
  34.                                 newA[y++]=oldA[i];//每被赋值一次,新数组的脚标数值+1以便下次赋值用
  35.                         }
  36.                 }
  37.                 for(int i=0;i<newA.length;i++)
  38.                         System.out.print(newA[i]+" ");//循环输出新数组
  39.                 }
  40.         }
复制代码

好吧。。。满足你。。不过感觉没必要太较真。。毕竟后面很快就会学到动态数组了。马上你就是不用跟小学奥数较真的大学生了哈,另外说下还是你的方法更好一些,那个人只是给你提供一个思路,虽然代码当时没实现得很好,提取有用的地方就好了。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马