Can't adept my plan to a loop logic

Hi there!
I came across a problem regarding loops.

For some reason, I want to check if there are double entries in my int array (rather String but nvm).
I came up with some kind of a solution, but I deeply hope there is a smarter way to do so:

String[] num = {"1", "1", "2", "3", "4", "5", "1", "8", "9", "9"};
int rand;

void setup() {
  size(400, 400);
  for (int i=0; i < 10; i++) {
    rand=(int)random(1, 4);
    num[i]=str(rand);
  }
  printArray(num);
  dublette();
}

void draw() {
}

void dublette() {
  int i=0;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  if ( num[i].equals( num[i+5]) ) { 
    num[i+5]="XXX";
  }
  if (num[i].equals( num[i+6]) ) { 
    num[i+6]="XXX";
  }
  if (num[i].equals( num[i+7]) ) { 
    num[i+7]="XXX";
  }
  if (num[i].equals( num[i+8]) ) {
    num[i+8]="XXX";
  }
  if (num[i].equals( num[i+9]) ) {
    num[i+9]="XXX";
  }
  i=1;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  if ( num[i].equals( num[i+5]) ) { 
    num[i+5]="XXX";
  }
  if (num[i].equals( num[i+6]) ) { 
    num[i+6]="XXX";
  }
  if (num[i].equals( num[i+7]) ) { 
    num[i+7]="XXX";
  }
  if (num[i].equals( num[i+8]) ) {
    num[i+8]="XXX";
  }
  i=2;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  if ( num[i].equals( num[i+5]) ) { 
    num[i+5]="XXX";
  }
  if (num[i].equals( num[i+6]) ) { 
    num[i+6]="XXX";
  }
  if (num[i].equals( num[i+7]) ) { 
    num[i+7]="XXX";
  }
  i=3;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  if ( num[i].equals( num[i+5]) ) { 
    num[i+5]="XXX";
  }
  if (num[i].equals( num[i+6]) ) { 
    num[i+6]="XXX";
  }
  i=4;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  if ( num[i].equals( num[i+5]) ) { 
    num[i+5]="XXX";
  }
  i=5;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  if (num[i].equals( num[i+4]) ) { 
    num[i+4]="XXX";
  }
  i=6;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  if (num[i].equals( num[i+3]) ) { 
    num[i+3]="XXX";
  }
  i=7;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 
  if (num[i].equals( num[i+2]) ) {
    num[i+2]="XXX";
  }
  i=8;
  if (num[i].equals( num[i+1])) {
    num[i+1]="XXX";
  } 

  println("cleaned:");
  printArray(num);
}

Because overall I’d like to check much bigger arrays for double entries ^^.
Could someone pleeease push me into a direction of applying this by (maybe even one single) loop(s)?

Because when I tried one big statement (if this || that || this…) I wasn’t able to replace that particular value.

1 Like

a little bit shorter version could be a double loop:

String[] num = {"1", "1", "2", "3", "4", "5", "1", "8", "9", "9"};

void setup() {
  printArray(num);
  dublette();
  println("no doubles");
  printArray(num);
}

void dublette() {
  int ilong=num.length;
  for (int i=0; i < ilong; i++) {
  String test = num[i];
    for (int k=0; k < ilong; k++) {
      if ( num[k].equals(test) && (k != i) ) {
          num[k] = "XXX";
        }      }    } 
}

but the timing sucks 2sec ( 0.6 sec for the printing alone) for 10.000

in a second attempt i could reduce that to half:
the 2 loops compared N * N times,
but actually only need (N-1) * (N/2)
the last one not need to check against anything, ( outer loop )
the inner loop not need to check on itself and all records prior to itself, so
i from 0 … N-1
k from i+1 … N

String[] snum; // = {"1", "1", "2", "3", "4", "5", "1", "8", "9", "9"};
int arraylong = 10000;
int randomlow = 0, randomhigh = 101;
long start, stop;
int repl=0;

boolean debug = true; //false;

//__________________________________________________________________
void setup() {
  make_snum(arraylong, randomlow, randomhigh);
  if (debug)   println(snum);
  dublette(debug);
  if (debug)   println(snum);
}

//__________________________________________________________________
void dublette(boolean debug) {
  start = millis();
  int ilong=snum.length;
  for (int i = 0; i < ( ilong - 1 ); i++) {
    String test = snum[i];
    for (int k = (i + 1); k < ilong; k++) {
      if ( snum[k].equals(test) && !snum[k].equals("XXX") ) {
        snum[k] = "XXX";
        if (debug)     println("check i: "+i+" has: "+test+" again at rec: "+k);
        repl++;
      }
    }
  }
  stop = millis();
  println((stop-start)+" msec for "+repl+" replacements");  // 782 msec for 9899 replacements

}

//__________________________________________________________________
void make_snum(int arraylong, int iLow, int iHigh) {
  snum=new String[arraylong];
  for (int i = 0; i<arraylong; i++) {
    snum[i] = str(int(random(iLow, iHigh)));
  }
}

so @GoToLoop “high level coding” possibly much faster.

1 Like
  1. Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Arrays.html#asList(T...)
  2. Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedHashSet.html#<init>(java.util.Collection)
  3. Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html#toArray(T[])
import java.util.Set;
import java.util.LinkedHashSet;

import static java.util.Arrays.asList;

String[] nums = { "1", "1", "2", "3", "4", "5", "1", "8", "9", "9" };
String[] uniqueNums;

void setup() {
  Set<String> uniques = new LinkedHashSet<String>(asList(nums));
  uniqueNums = uniques.toArray(new String[uniques.size()]);

  println(nums);       // 1 1 2 3 4 5 1 8 9 9
  println(uniqueNums); // 1 2 3 4 5 8 9

  exit();
}
2 Likes