【问题标题】:How to remove duplicated characters in char array, using java?如何使用java删除char数组中的重复字符?
【发布时间】:2016-11-02 06:42:29
【问题描述】:
public static void main(String[] args) 
{

    char[] x = {'b', 'l', 'a', 'h', 'h', ' '};
    char[] y = {'g', 'o', 'g', 'o'};

    System.out.println(removeDuplicate(x, y));
    System.out.println(noDuplicate(y, x));

public static char[] removeDuplicate(char[] first, char[] second)
{  

   //used my append method (didn't enclose) to append the two words together
   char[] total1 = append(first, second);

   //stores character that have been encountered
   char[] norepeat = new char[total1.length];

   int index = 0;

   //store result
   char[] solution = new char[total1.length];

   boolean found = false;

   //for loop keeps running until blahh gogo is over
   for(int i = 0; i < total1.length; i++)
   {
       for(int m = 0; m <norepeat.length; m++)
       {
            if(total1[i] == norepeat[m])
            {  
                found = true;
                break;
            }
   }

    if (!found)
       {   
           norepeat[index] = total1[i];
           index++;

           solution[index] = total1[i];
           index++;
       }
   }

   return solution;
}
}

电流输出:

blah

go

我希望输出是:

blah go

goblah (space at the end)

我的代码的问题是它在遇到第一次重复后停止运行,所以它甚至根本没有运行整个单词。我相信这与我的嵌套 for 循环有关,但我不确定。我试着把它写在纸上,但似乎没有任何帮助。

任何帮助将不胜感激!谢谢!

【问题讨论】:

  • 你在输出中最终得到goblah 的逻辑是什么?
  • 为什么你不使用 hashSet ?使用 HashSet 问题将在 O(N) 时间内解决。不要写已经写好的代码。
  • @TimBiegeleisen 在我打印出“System.out.println(noDuplicate(y, x));”时我现在正在从 y 到 x 读取 char[] - 因此从 gogo 到 blahh 读取。因此,在删除重复项后,我希望第二个输出是 goblah。希望我为您澄清了这一点。
  • @nikeshjoshi 我是一名初级 Java 程序员,现在正在学习我的基础知识。我还没有了解 HashSet...
  • 如果您当前的输出仅输出 first 的值(这似乎发生了),那么您的 append() 方法可能不起作用。 --- norepeatsolution 有什么区别?我的意思是,除了norepeat 获得分配的所有偶数索引和solution 获得分配的所有奇数索引之外,因为您在if (!found) 块中增加了两次index。 --- 也许你应该调试你的代码。见What is a debugger and how can it help me diagnose problems?

标签: java arrays netbeans char


【解决方案1】:

如果可能的字母是 ASCII 范围,那么您可以使用一个简单的布尔数组来跟踪您已经看到的字母:

boolean[] seen = new boolean[256];

如果不修改原始字符数组,则可以将唯一元素排列到数组的开头,然后创建第一个size元素的新数组并返回。

int size = 0;
for (int j = 0; j < chars.length; j++) {
    char c = chars[j];
    if (!seen[c]) {
        chars[size++] = chars[j];
        seen[c] = true;
    }
}
return Arrays.copyOf(chars, size);

如果字母表可以超过 ASCII 范围,您可以使用 Set&lt;Character&gt; 来跟踪看到的字符。

【讨论】:

    【解决方案2】:

    这是我使用 Map 和 List 作为助手的解决方案。保留作为 char 数组的输入和输出。

    请注意,您不应以 total1 的长度初始化 solution,否则 char 数组将在末尾打印空白。

    public static char[] removeDuplicate(char[] first, char[] second){  
    
       //used my append method (didn't enclose) to append the two words together
       char[] total1 = append(first, second);
    
       //stores character that have been encountered
       Map<Character,Boolean> norepeat = new HashMap<Character,Boolean>();
       //store partial result
       List<Character> partSolution=new ArrayList<Character>();
    
        //for loop keeps running until blahh gogo is over
        for(int i = 0; i < total1.length; i++){
            if(! norepeat.containsKey(total1[i])) {   
                norepeat.put(total1[i], true) ;
                partSolution.add(total1[i]);
            }
    
        }
    
        //store final result
        char[] solution = new char[partSolution.size()];
        for(int i=0;i<partSolution.size();i++){
           solution[i]=partSolution.get(i);
        }    
    
        return solution;
    

    }

    【讨论】:

      【解决方案3】:

      我认为您需要在第一个循环开始时将找到的变量分配为 false。在您的第一轮之后,found 的值始终为真。

      for(int i=0;i<total1.length;i++)
      {
       found=false;
       for(int m = 0; m <norepeat.length; m++)
         {      
              if(total1[i] == norepeat[m])
              {  
                  found = true;
                  break;
         }
      

      您也可以使用字符集代替字符数组。集是不允许重复元素的集合。有关更多信息。关于套装你可以访问这个链接。Sets

      【讨论】:

      • 内部循环之前,而不是在里面。
      • 我同意你的看法,它应该在第二个循环开始之前的第一个循环中
      【解决方案4】:

      如果您需要删除重复元素并保留数组的顺序,您可以使用LinkedHashSet。这是一个例子:

      Set<Character> x = new LinkedHashSet<Character>(Arrays.asList(new Character[]{'b', 'l', 'a', 'h', 'h', ' '}));
      Set<Character> y = new LinkedHashSet<Character>(Arrays.asList(new Character[]{'g', 'o', 'g', 'o'}));
      
      System.out.println(x);
      System.out.println(y);
      

      输出:

      [b, l, a, h,  ]
      [g, o]
      

      编辑。这是一个如何将 char[] 转换为 Character[] 的示例,反之亦然:

      char[] a = new char[]{'b', 'l', 'a', 'h', 'h', ' '};
      Character[] boxed = IntStream.range(0, a.length).mapToObj(i -> a[i]).toArray(size -> new Character[size]);
      char[] unboxed = IntStream.range(0, boxed.length).mapToObj(i -> String.valueOf(boxed[i])).collect(Collectors.joining()).toCharArray();
      

      【讨论】:

      • 输入是char[],而不是Character[],更改数组类型可能不合适。
      猜你喜欢
      • 2021-06-20
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 2016-06-04
      • 2014-03-20
      • 2011-04-26
      • 2011-09-26
      相关资源
      最近更新 更多