2017-01-24 9 views
1

Функция main принимает массив строк как аргумент и печатает одну строку вывода. вывод будет входом в таком порядке, чтобы первая буква каждой строки была такой же, как и последняя буква предыдущей строки, а также последняя буква последней строки такая же, как первая буква первой строки. Если заказ не существует, что включает в себя все строки, то код не будет печатать никакого решенияФункция Java, аналогичная словарной игре, последняя буква = первая буква следующего слова

Пример входных и выходные:

ввод: белок глаз klondlike LASIK

выхода: белки LASIK klondlike глаз

вход : почему мы не можем танцевать

выход: NO SOLUTION

вход: яблоко тампа слон

выход: яблочный слон тампа

Я написал большую часть кода, однако мой метод сортировки не работает для каждого теста из-за способа написано, что кто-нибудь сможет помочь ??

public class Ring { 

    public static void main(String[] args) { 

     boolean a = isFlip(args); 


     if(a) { 
      for (int i = 0; i < args.length; i++) { 
       System.out.print(args[i] + " "); 
      } 
     }else { 
      System.out.println("NO SOLUTION"); 
     } 

    } 

    public static boolean isFlip(String[] args) { 

     for (int i = 0; i <args.length ; i++) { 
      args[i]=args[i].toLowerCase(); 
     } 

     for (int i = 0; i < args.length-1 ; i++) { 
      for (int j = i+1; j <args.length ; j++) { 

       if (args[i].charAt(0)==(args[j].charAt(args[j].length()-1))){ 
        String s= args[j]; 
        args[j]=args[i]; 
        args[i]=s; 
       } 
      } 

     } 

     for (int i = 0; i <args.length-1 ; i++) { 
      if((args[i+1].charAt(0)!=(args[i].charAt(args[i].length()-1)))){ 
       return false; 
      } 

     } 
     if(args[args.length-1].charAt(args[args.length-1].length()-1)!=args[0].charAt(0)) return false; 

     return true; 
    } 
} 
+0

Я думаю * возможно * Я получаю то, что вы пытаетесь сделать, но, чтобы быть уверенным, можете ли вы отредактировать свой вопрос, чтобы включить некоторые примеры входов/выходов? –

+0

жаль, что я его отредактировал – myt

+0

Вы пробовали переходить через свой код с помощью отладчика? –

ответ

2

Вы можете попробовать с помощью рекурсивного подхода. Основная идея - проверить, что каждое слово - это другие слова, которые могут быть в цепочке.

private String[] findRing(String... words) { 
    for (int i = 0; i < words.length; i++) { 
     String word = words[i]; 
     String[] result = findRingForHeadAndTail(word, dropElementWithIndex(i, words)); 
     if ((result.length == words.length - 1) && 
       (word.charAt(0) == result[result.length - 1].charAt(result[result.length - 1].length() - 1))) { //word started from last letter in tail 
      return concatHeadAndTail(word, result); 
     } 
    } 
    return new String[]{"NO SOLUTION"}; 
} 

private String[] findRingForHeadAndTail(
     String head, //first word 
     String... tail //other words 
) { 
    if (tail.length == 0) { // if we don't have other words then just return empty array 
     return new String[0]; 
    } 

    if (tail.length == 1) { // if we have just one word in tail 
     if (tail[0].charAt(0) == head.charAt(head.length() - 1)) { //and this word begins with last letter in head 
      return tail; //return this tail 
     } else { 
      return new String[0]; //otherwise return empty array 
     } 
    } 

    for (int i = 0; i < tail.length; i++) { // for every word 
     String word = tail[i]; 
     if (word.charAt(0) == head.charAt(head.length() - 1)) { // if this word begins with last letter in head 
      String[] result = findRingForHeadAndTail(//recursive call for 
        word, //picked word 
        dropElementWithIndex(i, tail) // all other words in tail 
      ); 
      if (result.length == tail.length - 1) { // if recursive call returns the same amount of words as we passed there as tail 
       return concatHeadAndTail(word, result); //return array {head, tail} 
      } 
     } 
    } 
    return new String[0]; 
} 

//returns array as {head, tail} 
private String[] concatHeadAndTail(String head, String... tail) { 
    return Stream.concat(Stream.of(head), Stream.of(tail)).collect(Collectors.toList()).toArray(new String[tail.length + 1]); 
} 

//removes element with index i from words 
private String[] dropElementWithIndex(int i, String... words) { 
    List<String> result = new ArrayList<>(); 
    for (int j = 0; j < words.length; j++) { 
     if (j != i) { 
      result.add(words[j]); 
     } 
    } 
    return result.toArray(new String[words.length - 1]); 
} 

И выход для:

@Test 
public void findRing() { 
    System.out.println(Arrays.toString(findRing("squirrel", "eyes", "klondlike", "lasik"))); 
    System.out.println(Arrays.toString(findRing("why", "cant", "we", "dance"))); 
    System.out.println(Arrays.toString(findRing("apple", "tampa", "elephant"))); 
    System.out.println(Arrays.toString(findRing("apple", "elephant", "tampa"))); 
    System.out.println(Arrays.toString(findRing("elephant", "apple", "tampa"))); 
    System.out.println(Arrays.toString(findRing("alfa", "alfa", "beta"))); 
    System.out.println(Arrays.toString(findRing("alfa", "alfa"))); 
    System.out.println(Arrays.toString(findRing("alfa", "alfa", "bravo"))); 
} 

является:

[squirrel, lasik, klondlike, eyes] 
[NO SOLUTION] 
[apple, elephant, tampa] 
[apple, elephant, tampa] 
[elephant, tampa, apple] 
[NO SOLUTION] 
[alfa, alfa] 
[NO SOLUTION] 

UPDATE Предыдущее решение имеет сложность O (N!) В худшем случае. Различные решения были предложены FDesu и основаны на одном из свойств Adjacency matrix.

Если А матрица смежности направленного или ненаправленного графа G, то матрица Ап (т.е. матрица произведение п экземпляров А) имеет интересную интерпретацию: элемент (I, J) дает количество (направленных или неориентированных) прогулок длины n от вершины i до вершины j.

Этот алгоритм имеет сложность O (n^4), но также имеет дополнительные требования к памяти, поскольку мы должны хранить все возможные пути.

private void findRingWithMatrix(String... words) { 
    System.out.println("For example: " + Arrays.toString(words)); 
    boolean[][] initialAdjacencyMatrix = new boolean[words.length][words.length]; 
    List<String[]> paths = new ArrayList<>(); 
    //Build initial adjacency matrix 
    for (int i = 0; i < words.length; i++) { 
     for (int j = 0; j < words.length; j++) { 
      initialAdjacencyMatrix[i][j] = (i != j) && (couldBeInChain(words[i], words[j])); 
      //if node is reachable 
      if (initialAdjacencyMatrix[i][j]) { 
       //put this path to possible paths 
       paths.add(new String[]{words[i], words[j]}); 
      } 
     } 
    } 

    //create temporary copy of matrix to multiply 
    boolean[][] tempAdjacencyMatrix = initialAdjacencyMatrix.clone(); 

    //We should multiply matrix N-1 times, because first step in graph we've already done on previous step 
    for (int n = 1; n < words.length; n++) { 
     boolean[][] bufferAdjacencyMatrix = new boolean[words.length][words.length]; 

     List<String[]> newPathes = new ArrayList<>(); 

     //multiply matrices (next step and initial). In result we get [true] in node which is reachable from first node in N steps 
     for (int i = 0; i < words.length; i++) { 
      for (int j = 0; j < words.length; j++) { 
       for (int k = 0; k < words.length; k++) { 
        bufferAdjacencyMatrix[i][j] |= (tempAdjacencyMatrix[i][k] && initialAdjacencyMatrix[k][j]); 
       } 
       //if node reachable 
       if (bufferAdjacencyMatrix[i][j]) { 
        //create new path and put it list of possible paths 
        for (String[] path : paths) { 
         if (couldBeInChain(path[path.length - 1], words[j])) { 
          String[] newPath = new String[path.length + 1]; 
          System.arraycopy(path, 0, newPath, 0, path.length); 
          newPath[newPath.length - 1] = words[j]; 
          newPathes.add(newPath); 
         } 
        } 
       } 
      } 
     } 
     paths = removeDuplicates(newPathes); 
     System.out.println("Step #" + n); 
     printMatrix(bufferAdjacencyMatrix); 
     tempAdjacencyMatrix = bufferAdjacencyMatrix; 
    } 

    boolean isRing = true; 

    //Ring could be just if after (N-1) multiplications we have [true] in main diagonal. 
    //In other words, can reach every node in N steps. 
    for (int i = 0; i < words.length; i++) { 
     isRing = tempAdjacencyMatrix[i][i]; 
     if (!isRing) { 
      break; 
     } 
    } 

    if (!isRing) { 
     System.out.println("NO SOLUTION"); 
     return; 
    } else { 

     System.out.println("Found solutions:"); 
     for (String[] path : paths) { 
      //we are interested just in solutions when first node is equals to last one 
      if (path[0].equals(path[path.length - 1])) { 
       String[] toPrint = new String[path.length - 1]; 
       System.arraycopy(path, 0, toPrint, 0, toPrint.length); 
       System.out.println(Arrays.deepToString(toPrint)); 
      } 
     } 
    } 

    System.out.println("=============================="); 
} 

private boolean couldBeInChain(String first, String second) { 
    return first.charAt(first.length() - 1) == second.charAt(0); 
} 

private List<String[]> removeDuplicates(List<String[]> newPathes) { 
    return newPathes 
      .stream() 
      .map(Arrays::asList) 
      .collect(Collectors.collectingAndThen(Collectors.toSet(), new Function<Set<List<String>>, List<String[]>>() { 
       @Override 
       public List<String[]> apply(Set<List<String>> lists) { 
        List<String[]> result = new ArrayList<>(); 
        for (List<String> list : lists) { 
         result.add(list.toArray(new String[list.size()])); 
        } 
        return result; 
       } 
      })); 
} 

private void printMatrix(boolean[][] matrix) { 
    System.out.println("-------------------------------"); 

    for (boolean[] row : matrix) { 
     System.out.println(Arrays.toString(row)); 
    } 
    System.out.println("-------------------------------"); 
} 
+0

Имеет ли этот код что-то вроде ввода: «яблоко», «тампа», «тад», «точка», «слон», с выходом: «яблоко», «слон», «тад», «точка», «тампа» «? –

+0

@TJamesBoone да, проверено. вывод: '[яблоко, слон, тад, точка, тампа]' –

+0

Сладкий. Это означает, что он может справиться с этой проблемой. Престижность для большого использования рекурсии! –

 Смежные вопросы

  • Нет связанных вопросов^_^