void RemoveDups(){
int f=0;
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
{
arr[k]=arr[k+1];
}
nelems--;
}
if(i==(nelems+1)){
f++;
i=f+1; //increment again
}
}
}
这是我编写的用于从数组中删除重复元素的逻辑,但这根本不起作用?我应该做些什么改变才能使它工作?或者考虑到时间复杂性,人们有更好的逻辑来做同样的事情。我不想使用内置方法来实现这一目标。
答案 0 :(得分:1)
int end = input.length;
for (int i = 0; i < end; i++) {
for (int j = i + 1; j < end; j++) {
if (input[i] == input[j]) {
int shiftLeft = j;
for (int k = j + 1; k < end; k++, shiftLeft++) {
input[shiftLeft] = input[k];
}
end--;
j--;
}
}
}
答案 1 :(得分:0)
你有两个选项, C#有一个Distinct()Linq表达式,它将为你做这个(错过了Java标签),但是如果你需要删除项目,你有没有考虑过排序首先列出,然后将当前项目与前一项目进行比较,如果它们相同,则将其删除。这意味着您的二次检测只能在阵列中运行一次。
如果您担心排序,可以轻松实现有效的冒泡排序或实现这种效果
答案 2 :(得分:0)
我认为你可以使用Set Collection
将所有值复制到HashSet,然后使用Iterator访问值
Set<Integer> hashset= new HashSet<Integer>();
答案 3 :(得分:0)
在将examlpe arr [0]与arr [5]进行比较后,您永远不会减少i
,您永远不会测试arr[1] == arr[2]
你需要在增加f。
之后开始一个新循环(i)试
for(int f=0;f<nelems-1;f++)
{
for(int i=f+1;i<nelems;i++)
{
...
}
}
使用这个嵌套的for循环,你可以比较数组的每两个元素。
答案 4 :(得分:0)
一个好的开始是消除重复元素而不缩小最后完成的数组:
public class run2 extends Thread {
public static void main(String[] args) {
int arr[] = { 1, 2, 2, 3, 5, 6, 5, 5, 6, 7 };
for (int i = 0; i < arr.length; i++) {
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] == -1)
j++;
if (arr[i] == arr[j])
arr[j] = -1;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
if (arr[i] == -1) {
for (int j = i; j < arr.length; j++) {
if (arr[j] != -1) {
arr[i] = arr[j];
arr[j] = -1;
break;
}
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ",");
}
}
}
答案 5 :(得分:0)
据我所知,从你的代码中,你将每个从索引0开始的值与元素的其余部分进行比较,当你看到位于索引f的元素时,你试图移动整个数组并递减数组的大小(nelems)。看看行号。 11
if(i==(nelems+1)){
f++;
i=f+1;
问题是当我被设置为f + 1时,我将再次在for循环中递增以进行下一次迭代。所以基本上我开始从f + 2开始比较。而且你也在比较我(nelems + 1) )考虑到nelems递减的情况,但你没有考虑这种情况,当我到达终点而不减少nelems在那种情况下我永远不会等于(nelems + 1)。现在考虑你的逻辑,你可以做2件事。
1.这是你的工作代码。
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i+1;k<nelems;k++)
{
arr[k-1]=arr[k];
}
if(i==(nelems-1)){
f++;
i=f;
}
nelems--;
}
if(i==(nelems-1)){//end of the loop
f++;
i=f; //increment again
}
}
2.你可以使用外部for循环,一旦内部for完成,它将增加f值。
void RemoveDups(){
for(int f=0;f<nelems;++f){
for(int i=1;i<nelems;i++){
if(arr[f]==arr[i]){
for(int k=i;k<nelems;k++)
arr[k]=arr[k+1];
nelems--;
}
}
}
}
现在您的问题已经解决,但代码的时间复杂度将为(O(N ^ 3))。
现在不用在第4行移动整个数组,而只需将arr [f]与最后一个元素交换。
if(arr[f]==arr[i]){
swap(arr[f],arr[nelems-1]);
nelems--;
}
它会将时间复杂度从O(N ^ 3)减少到O(N ^ 2)。
现在我建议你使用我的方法
1.只需对数组进行排序。它将在O(NlogN)中完成。 2.现在使用一个for循环你可以得到你想要的东西。
void RemoveDups(){
int k=0,i;
for(i=1;i<nelems;++i){
while(arr[i]==arr[i-1])
++i;
arr[k++]=arr[i-1];
}
arr[k++]=arr[i-1];
}
现在基本上你有一个大小为k的数组,它按排序顺序包含非重复元素,我的解决方案的时间复杂度为O(NlogN)。
答案 6 :(得分:0)
改编此代码:
public static int[] removeDuplicates(int[] numbersWithDuplicates) {
// Sorting array to bring duplicates together
Arrays.sort(numbersWithDuplicates);
int[] result = new int[numbersWithDuplicates.length];
int previous = numbersWithDuplicates[0];
result[0] = previous;
for (int i = 1; i < numbersWithDuplicates.length; i++) {
int ch = numbersWithDuplicates[i];
if (previous != ch) {
result[i] = ch;
}
previous = ch;
}
return result;
}