Java函数类似于文字游戏,最后一个字母=下一个单词的第一个字母

时间:2017-01-24 21:00:12

标签: java sorting arguments

函数main接受一个字符串数组作为争论,并将打印一行输出。输出将按顺序输入,使得每个字符串的第一个字母与前一个字符串的最后一个字母相同,但最后一个字符串的最后一个字母与第一个字符串的第一个字母相同。如果不存在包含所有字符串的订单,则代码将不打印解决方案

输入和输出示例:

输入:松鼠的眼睛klondlike lasik

输出:squirrel lasik klondlike eyes

输入:为什么我们不能跳舞

输出:无解决方案

输入:apple tampa elephant

输出:apple elephant tampa

我编写了大部分代码但是我的排序方法并不适用于每个测试用例,因为它的编写方式,是否有人能够提供帮助?

<coordinator-app name="${jobName}" frequency="${coord:days(1)}" start="2000-01-01T12:00Z" end="3000-01-01T12:00Z" timezone="UTC" xmlns="uri:oozie:coordinator:0.2">
    <controls>
        <timeout>-1</timeout>
        <concurrency>1</concurrency>
        <execution>LAST_ONLY</execution>
    </controls>

    <action>
        <workflow>
            <app-path>${myAppPath}</app-path>
        </workflow>
    </action>
</coordinator-app>

2 个答案:

答案 0 :(得分:3)

您可以尝试使用递归方法。主要思想是检查每个单词是否可能在链中。

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的一个属性。

  

如果A是有向图或无向图G的邻接矩阵,那么矩阵An(即A的n个副本的矩阵乘积)具有一个有趣的解释:元素(i,j)给出的数量(有向或无向的)从顶点i到顶点j的长度为n的步长。

该算法具有复杂度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("-------------------------------");
}

答案 1 :(得分:1)

class T
{
public static void main(String[] args) 
{ 
int k=1;
Scanner sc=new Scanner(System.in); 
String str=sc.nextLine(); 
String[] word=str.split(" "); 
StringBuilder str1=new StringBuilder(word[0]); 
while(str1.toString().length()!=str.length())
{ 
for(int j,i=1;i<word.length;i++)
{ 
for(j=1;j<word.length;j++)
{
if((str1.toString()).endsWith(Character.toString(word[j].charAt(0))))
{ 
str1.append(" "+word[j]);
} 
} 
}
break;
}
for(int i=0;i<word.length;i++)
{
    if((str1.toString()).indexOf(word[i])<0)
    {
        str1.insert(0,word[i]+" ");
        k=k+1;
    }
}
if(k==word.length)
    System.out.println(str);
else
    System.out.println("NO SOLUTION"); 
} 
}