我正在尝试从数组中删除重复项,但它无效。
我错过了什么吗?
代码: -
class RemoveStringDuplicates {
public static char[] removeDups(char[] str) {
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
str[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return str;
}
public static void main(String[] args) {
char str[] = "test string".toCharArray();
System.out.println(removeDups(str));
}
}
输出: -
tes ringing //ing should not have been repeated!
答案 0 :(得分:2)
您应该使用新数组,而不是将字符分配到同一个数组中。因为,在删除重复项后,不会删除尾随元素,因此会打印出来。
因此,如果使用新数组,则尾随元素将为null
个字符。
所以,只需创建一个新数组:
char[] unique = new char[str.length];
然后更改作业:
str[res_ind] = str[ip_ind];
为:
unique[res_ind] = str[ip_ind];
此外,您可以考虑使用ArrayList
代替array
。这样你就不必为每个角色维护一个boolean
数组,这太过分了。你正在失去一些不需要的额外空间。使用ArrayList
,您可以使用contains
方法检查已添加的字符。
嗯,您还可以使用Set
手动避免手动执行所有这些计数工作,这会自动为您删除重复项。但大多数实现都不维护插入顺序。为此,您可以使用LinkedHashSet
。
答案 1 :(得分:1)
具体问题已经找到了解决方案,但是如果您没有限制使用自己的方法并且可以使用java库,我会建议这样的事情:
public class RemoveDuplicates {
// Note must wrap primitives for generics
// Generic array creation not supported by java, gotta return a list
public static <T> List<T> removeDuplicatesFromArray(T[] array) {
Set<T> set = new LinkedHashSet<>(Arrays.asList(array));
return new ArrayList<>(set);
}
public static void main(String[] args) {
String s = "Helloo I am a string with duplicates";
Character[] c = new Character[s.length()];
for (int i = 0; i < s.length(); i++) {
c[i] = s.charAt(i);
}
List<Character> noDuplicates = removeDuplicatesFromArray(c);
Character[] noDuplicatesArray = new Character[noDuplicates.size()];
noDuplicates.toArray(noDuplicatesArray);
System.out.println("List:");
System.out.println(noDuplicates);
System.out.println("\nArray:");
System.out.println(Arrays.toString(noDuplicatesArray));
}
}
出:
List:
[H, e, l, o, , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]
Array:
[H, e, l, o, , I, a, m, s, t, r, i, n, g, w, h, d, u, p, c]
linkedhashset保留了排序,这对于像字符集这样的事情可能尤为重要。
答案 2 :(得分:0)
试试这个:
public static char[] removeDups(char[] str) {
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
char a[] = new char[str.length];
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
a[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return a;
}
你基本上是在循环中更新str变量。更新它并再次循环更新的数组。
答案 3 :(得分:0)
我认为问题是由于您在修改str
时进行迭代(由行str[res_ind] = str[ip_ind]
)引起的。如果将结果复制到另一个数组,它可以工作:
class RemoveStringDuplicates {
public static char[] removeDups(char[] str) {
char result[] = new char[str.length];
boolean bin_hash[] = new boolean[256];
int ip_ind = 0, res_ind = 0;
char temp;
while (ip_ind < str.length) {
temp = str[ip_ind];
if (bin_hash[temp] == false) {
bin_hash[temp] = true;
result[res_ind] = str[ip_ind];
res_ind++;
}
ip_ind++;
}
return result;
}
public static void main(String[] args) {
char str[] = "test string".toCharArray();
System.out.println(removeDups(str));
}
}
答案 4 :(得分:0)
所有其他答案似乎都是正确的。您在结果末尾看到的“ing”实际上是数组中已经存在的未触摸字符。
作为替代解决方案(如果你想节省内存),你可以循环遍历数组的最后一部分以删除最后的字符,因为你已经知道它们是重复的。
//C# code, I think you just need to change str.Length here to str.length
for (int delChars = res_ind; delChars < str.Length; delChars++)
{
str[delChars] = '\0';
}
答案 5 :(得分:0)
您完全滥用Java语言和代码。标准库中的数据结构类是使用Java 的要点。使用它们。
正确的编码方式来做你想做的事情就在这里:
class RemoveStringDuplicates {
public static String removeDups(CharSequence str) {
StringBuilder b = new StringBuilder(str);
HashSet<Character> s = new HashSet<Character>();
for(int idx = 0; idx < b.size(); idx++)
if(mySet.contains(b.charAt(idx)))
b.deleteCharAt(idx--);
else
s.add(ch);
return b.toString();
}
public static void main(String[] args) {
System.out.println(removeDups(str));
}
}
也可能有更好的方法。不要避免使用Java的数据结构。
如果您编写的代码对性能非常敏感,您必须使用问题中的原始代码,那么您应该使用其他语言,例如C.