2017-03-05 107 views
1

我一直在尝试解决此任务可能已经超过一个小时了。 我需要从字符串中删除所有重复项,但棘手的部分是,如果一个字母重复并且奇数次,该字母的一个副本应该保留在最后一个字符串中。例如,一串assdafff应该转换为df,因为f呈现奇数次。我设法制作一个程序来删除所有重复的内容,但我无法找到那些在那里出​​现奇数次的内容。 重要的是保持输入字符串中遇到的元素的顺序与输入中相同。查找并删除所有重复的字符串,除非它们重复奇数次

public static void main(String[] args){   
Scanner reader = new Scanner(System.in); 
String x = reader.nextLine(); 
String ne = ""; 
StringBuffer buf = new StringBuffer(x.length() -1); 
for(int i=0; i<x.length(); i++){ 
    for(int v = 0; v<x.length(); v++){ 
     if((x.charAt(i)==x.charAt(v))&&(i!=v)){ 
      break; 
    } 
    if((v==x.length()-1)&&(i!=v)){ 
     ne+=x.charAt(i); 
    }} 
} 
if(ne.equals("")){ 
    System.out.println("Empty String"); 
}else{ 
System.out.println(ne); 
} 
} 

回答

1

我会使用一个类似于其他答案的地图,但问题在于它没有以有序的方式存储键/值对,所以我使用了两个ArrayLists来存储字符及其等价物计数。 这里有一个工作的解决方案:

String string = "thisisastring"; 

StringBuffer buffer = new StringBuffer(); 
ArrayList<Character> chars = new ArrayList<>(); 
ArrayList<Integer> counts = new ArrayList<>(); 

for(int i= 0; i< string.length(); i++) 
{ 
    char curChar = string.charAt(i); 
    int charIndex; 
    // if curChar already exists in chars, increment its count  
    if((charIndex = chars.indexOf(curChar))>-1) 
    { 
    counts.set(charIndex, counts.get(charIndex)+1); 
    } 
    else // else add it to chars and add its count which is 1 to counts 
    { 
    chars.add(curChar); 
    counts.add(1); 
    } 
} 

for(int i= 0; i< chars.size(); i++) 
    // if char count is odd, add it to the buffer 
    if(counts.get(i)%2!=0) 
    buffer.append(Character.toString(chars.get(i))); 

System.out.println(buffer.toString()); // prints hisarng 

编辑:为@Federico佩拉尔塔夏弗纳提到的,你也可以使用一个LinkedHashMap如下:

String string = "thisisastring"; 
StringBuffer buffer = new StringBuffer(); 
LinkedHashMap<Character, Integer> linkedHashMap = new LinkedHashMap<>(); 

for(int i=0; i< string.length(); i++) 
{ 
    char curChar = string.charAt(i); 
    linkedHashMap.put(curChar, linkedHashMap.containsKey(curChar)?linkedHashMap.get(curChar)+1:1); 
} 

for(Map.Entry<Character, Integer> entry : linkedHashMap.entrySet()) 
    if(entry.getValue()%2 !=0) 
    buffer.append(entry.getKey()); 

System.out.println(buffer.toString()); // prints hisarng 
+0

您可以使用'LinkedHashMap'来保持插入顺序 –

+0

@FedericoPeraltaSchaffner哦,是的,你说得对,谢谢指出。 –

+2

@FedericoPeraltaSchaffner我编辑我的答案来说明你的建议,如果你不介意^^ –

0

1迭代并使用Map < Char,Integer>来保持计数。

2迭代一次只保留字符与奇计

String string = "deadbeef"; 

// ALL COUNTS 
Map<Character,Integer> counts=new HashMap<Character,Integer>(); 

for(int i= 0; i< string.length(); i++) 
    { 
    char c = string.charAt(i); 

    if (counts.containsKey(c)) 
    counts.put(c,counts.get(c)+1); 
    else 
     counts.put(c, 1); 
    } 

// RESULT 
String result=""; 

// ALLREADY USED 
Set<Character> set=new HashSet<Character>(); 

for(int i= 0; i< string.length(); i++) 
    { 
    char c = string.charAt(i); 

     // ODD AND FIRST 
     if ((counts.get(c)%2==1) 
      &&(!set.contains(c))) 
      result+=c; 

    set.add(c); 
    } 

System.out.println("RESULT:"+result); // => eabf 
+0

是什么地图?我有使用单独for循环寻找奇数重复的想法,但最终的字符串应该有字母 – Mik

+0

的原始位置,请参阅https://docs.oracle.com/javase/7/docs/api/java/util/Map .html。你是初学者,是吗? –

+0

是的,我从来没有使用地图 – Mik

-1

你可以在短短一个迭代解决这个问题。首先,您需要保存第一次遇到的字符的位置。如果再次遇到它们,请删除当前的和之前遇到的那个。例如,你有

s = "assdafff" 

对于所有第一次遇到字符您

for(i = 0; i<s.length(); i++) 
    if(dict.get(s[i]) == null) // 
    dict[s[i]] = i; 

和其他

else // which means it's duplicate 
    delete both s[i] and s[dict.get(s[i])] from string 

拯救他们,不要忘记删除当前映射条目以及。

+0

但是什么是字典? – Mik

+0

对不起,忘了提及,字典与地图有相同的数据结构。把它们看作数组,但索引可以是除整数之外的任何其他数据。但是,只需使用数组即可脱身。我非常确定,而不是'dict ['a'] = 0',你可以使用'dict [Character.getNumericValue('a')] = 0'。我希望这使得sese – hikmathaji

+0

这个问题是关于Java,你提供了一个Python解决方案^^两种语言之间的东西是相当不同的。 –

2

的算法很简单。正如其他人指出的那样,您可以将字符串的每个字符的计数存储在地图中,然后仅保留具有奇数的地图条目。为了保留广告订单,您应该使用LinkedHashMap。然后,我们将地图的键合并成一个新的字符串。

一个Java 8的解决办法如下:

String string = "string-123-string"; 

Map<Integer, Long> map = string.chars() 
     .boxed() 
     .collect(Collectors.groupingBy(
       Function.identity(), 
       LinkedHashMap::new, 
       Collectors.counting())); 

map.values().removeIf(count -> count % 2 == 0); 

String result = map.keySet().stream() 
     .map(i -> new char[] { (char) i.intValue() }) 
     .map(String::new) 
     .collect(Collectors.joining()); 

System.out.println(result); // 123 
+0

当我测试这段代码时,发现错误并给出了未知的错误http://prntscr.com/egw4be – Mik

+0

@Mik我相信这个错误是由于你的'x'变量是'null' –

+0

或者,也许这是因为代码不能编译,也就是说你缺少'LinkedHashMap'导入语句,并且包名似乎也有错误......它是否与目录名称相同?无论如何,我测试了我的答案代码,并且一切都很完美。 –