4

char_array[] is "x, a, x, c, x, b, x, a, x, x ,b ,x ,x, x, x"

key_array[] is "a, b, c"

expected return array: "1, 5, 3"

The goal is to print the index of the char_array that matches with key_array. For example, in this case the program has to print "1, 5, 3". It only counts the first index it matches.

Another example would be that

char_array[] is "q, h, e, h, w, e, r, t, l, y, l, l, o"

key_array[] is "h, e, l, l, o"

expected return array: "1, 2, 8, 10, 12"

What I have tried so far is

int index = 0;
for(int i = 0; i < key_array.length; i++)
{
    isFound = false;
    for(int k = index + 1; k < char_array.length && isFound == false; k++) 
    {
        if(char_array[i] == key_array[k])
        {
            index = k;
            num[j] = index;
            isFound = true;
        }
    }
}

This way, my second example which deals with "hello" works but my first example which deals with "abc" doesn't work.

I started my k with index+1, but I guess I will have to change this from 0 to char_array.length..

Can someone help me with this logic please

9
  • Hint: loop over the "key" array, and for each char C, loop over the other array and when you find the C print the index and break, then repeat Commented Sep 16, 2016 at 6:03
  • 2
    Why wouldn't the "h, e, l, l, o" version output "1, 2, 8, 8, 12"? Commented Sep 16, 2016 at 6:04
  • 1
    You need to take are of reinitializing index to 0 Commented Sep 16, 2016 at 6:05
  • @Tibrogargan because 8 is already counted. So it shouldn't be counted again. Commented Sep 16, 2016 at 6:06
  • @user7 but when I reinitialize index to 0, it counts the index again like in hello example above, it shouldn't print 1 2 8 8 12, it should be 1 2 8 10 12 Commented Sep 16, 2016 at 6:09

5 Answers 5

2

Try this;

for(int i=0;i<key_array.length;i++)
{
    int pos=new String(char_array).indexOf(key_array[i]);

    char_array[pos]='0'                          //considering there is no numeric character in char_array  

    collection.push(pos);                        //collection is a java Collection framework's object
}
Sign up to request clarification or add additional context in comments.

6 Comments

Why not? char_array never is updated. It's pointless to recreate the string inside the loop
@cricket_007 so he can use indexOf. Tricky. Too bad the output is wrong, this would be a nice solution
Also, this doesn't take into account repeating characters can't have the same number. See the "hello" example
I thought you were asking to to keep whole statement out side of the loop.
Moving the String creation outside the loop is really just an optimization the compiler would have done anyway. The real problem is that the solution produces an incorrect result
|
0

Seems to do the trick

static int[] foo(char[] char_array, char[] key_array) {
    // copy the original so we can modify to avoid repeats
    char[] copy = new char[char_array.length];
    System.arraycopy(char_array, 0, copy, 0, char_array.length);
    int[] result = new int[key_array.length];
    boolean found = true;
    for(int i = 0; found && i < key_array.length; i++) {
        found = false;
        for(int j = 0; j < copy.length; j++) {
            if (copy[j] == key_array[i]) {
                copy[j] = 0;
                result[i] = j;
                found = true;
                break;
            }
        }
    }
    if (found) {
        return result;
    }
    return null;
}

public static void main(String[] args) {
    System.out.println(Arrays.toString(foo("xaxcxbxaxxbxxxx".toCharArray(), "abc".toCharArray())));
    System.out.println(Arrays.toString(foo("qhehwertlyllo".toCharArray(), "hello".toCharArray())));
}

Comments

0

This only works for the second example, since the chars occur in order.

However you need to decide the index to start the search based on whether you've seached the string for this char before (start after the char found).

E.g.

for (int i = 0; i < key_array.length; i++) {
     char c = key_array[i];
     int previousIndex;

     // go back and find the last index with a matching char
     for (previousIndex = i-1; previousIndex >= 0 && key_array[previousIndex] != c; previousIndex--) {}

     if (previousIndex >= 0 && num[previousIndex] == -1) {
          // last key not found => no further matches available
          num[i] = -1;
     } else {
          // find occurence of char after last match
          num[i] = -1;
          for (int j = (previousIndex >= 0 ? num[previousIndex] + 1 : 0); j < char_array.length; j++) {
               if (char_array[j] == c) {
                    num[i] = j;
                    break;
               }
          }
     }
}

Alternatively use a Map to store the indices by char and use this to retrieve the indices efficiently:

// find list of indices by char
Map<Character, ?> map = IntStream.range(0, char_array.length).boxed().collect(Collectors.groupingBy(i -> char_array[i]));

for (Map.Entry e : map.entrySet()) {
    // replace values with iterator over index lists
    e.setValue(((List)e.getValue()).iterator());
}

for (int i = 0; i < key_array.length; i++) {
    Iterator<Integer> iterator = (Iterator<Integer>) map.get(key_array[i]);
    num[i] = (iterator == null || !iterator.hasNext() ? -1 : iterator.next());
}

Comments

0

Hello this shoul do the trick!

public class Main
{

  private static final char[] liste1 = {'x', 'a', 'x', 'c', 'x', 'b', 'x', 'a', 'x', 'x' ,'b' ,'x' ,'x', 'x', 'x'};
  private static final char[] liste2 = {'q', 'h', 'e', 'h', 'w', 'e', 'r', 't', 'l', 'y', 'l', 'l', 'o'};
  private static final char[] key1 = {'a', 'b', 'c'};
  private static final char[] key2 = {'h', 'e', 'l', 'l', 'o'};


  private static void lookupIndexOfChar(char c, char[] list, List<Integer> result){
    for(int i = 0; i < list.length; i++){
      if(list[i] == c){
        if(notInResult(i, result)){
          result.add(i);
          break;
        }
      }
    }
  }

  private static boolean notInResult(int i, List<Integer> result)
  {
    return !(result == null || result.contains(i));
  }

  public static void main(String[] args){
    List<Integer> result = new ArrayList<Integer>();
    for (char c : key1)
    {
      lookupIndexOfChar(c, liste1, result);
    }
    for (Integer integer : result)
    {
      System.out.print(integer);
    }
    System.out.println(" ");
    result.clear();
    for (char c : key2)
    {
      lookupIndexOfChar(c, liste2, result);
    }
    for (Integer integer : result)
    {
      System.out.print(integer);
    }
  }

}

Comments

0

I think this will do the job ( O(n) ) :

char[] char_array = {'q', 'h', 'e', 'h', 'w', 'e', 'r', 't', 'l', 'y', 'l', 'l', 'o'};
char[] key_array = {'h', 'e', 'l', 'l', 'o'};

Map<Character, Queue<Integer>> charPossitions = new HashMap<Character, Queue<Integer>>();
for(int i = 0; i < char_array.length; i++){
    if(charPossitions.get(char_array[i]) == null){           
       Queue<Integer> possitionsQueue=new LinkedList<Integer>();
       possitionsQueue.add(i);
       charPossitions.put(char_array[i], possitionsQueue);
    }else { 
       charPossitions.get(char_array[i]).add(i);
    }                                           
}
for(char key : key_array){
    System.out.println(key + "/" + charPossitions.get(key).poll());
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.