3 回答

TA貢獻2037條經驗 獲得超6個贊
我做了大多數人可能認為是蠻力方法的事情。本質上,我通過為每個塊維護一個獨立的索引來按順序創建每個可能的單詞。然后我將創建的詞與所需的詞進行比較。我還打印出用于構建每個成功的位置。一些額外的開銷是我允許具有不同面數的塊。最后,可能存在錯誤。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Blocks {
public static void main(String[] args) {
// input parameters
int nBlocks = 5;
String wordToFind = "nifty";
// block sizes may have different number of sides
// This permits optimization by removing irrelevant letters
// (which I didn't do).
String[] blockStrings = { "ffi", "rnnf", "aeif", "drst","vyxksksksksky"
};
// Split the blocks into a list of letter arrays
List<String[]> blocks =
Arrays.stream(blockStrings).map(s -> s.split("")).collect(
Collectors.toList());
// turn "foobar" into abfoor"
String[] word = wordToFind.split("");
String sortedWord =
Arrays.stream(word).sorted().collect(Collectors.joining());
int count = 0;
int[] k = new int[nBlocks];
String[] w = new String[nBlocks];
// calculate maximum number of iterations. The product
// of all the block's faces for n blocks.
int end = blocks.stream().mapToInt(a -> a.length).reduce(1,
(a, b) -> a * b);
for (int ii = 0; ii < end; ii++) {
List<Integer> usedBlockPositions = new ArrayList<>();
for (int i = 0; i < nBlocks; i++) {
w[i] = blocks.get(i)[k[i]];
usedBlockPositions.add(k[i]);
}
// compare sorted word to sorted "found" word to see if there is
// a match.
if (sortedWord.equals(
Arrays.stream(w).sorted().collect(Collectors.joining()))) {
count++;
System.out.println(Arrays.toString(w) + " " + usedBlockPositions);
}
// Bump the indices to the blocks for next try. This is used to
// index into each block face to get the next letter. Once
// again, this is written to allow variable faced blocks.
// k starts out as [0,0,0,0]
// then goes to [1,0,0,0], [2,0,0,0] etc thru to [n1,n2,n3,n4] where
// n* is the max number of block faces for given block. The size of
// k is the number of blocks (this shows 4).
for (int i = 0; i < k.length; i++) {
int v = k[i];
if (v >= blocks.get(i).length - 1) {
k[i] = 0;
}
else {
k[i]++;
break;
}
}
}
String format = count != 1 ? "%nThere were %d combinations found.%n"
: "%nThere was %d combination found.%n";
System.out.printf(format, count);
}
}
發布的代碼打印以下內容。
[f, n, i, t, y] [0, 1, 2, 3, 1]
[f, n, i, t, y] [1, 1, 2, 3, 1]
[f, n, i, t, y] [0, 2, 2, 3, 1]
[f, n, i, t, y] [1, 2, 2, 3, 1]
[i, n, f, t, y] [2, 1, 3, 3, 1]
[i, n, f, t, y] [2, 2, 3, 3, 1]
[f, n, i, t, y] [0, 1, 2, 3, 12]
[f, n, i, t, y] [1, 1, 2, 3, 12]
[f, n, i, t, y] [0, 2, 2, 3, 12]
[f, n, i, t, y] [1, 2, 2, 3, 12]
[i, n, f, t, y] [2, 1, 3, 3, 12]
[i, n, f, t, y] [2, 2, 3, 3, 12]
There were 12 combinations found.

TA貢獻1869條經驗 獲得超4個贊
我不完整的想法如下:塊放在一個數組中,它的索引作為每個塊的唯一標識。然后你構建一個列表映射:Map<String, List<Integer>>其中鍵是目標單詞中字母的出現(因此對于單詞“food”,字母“o”應該在映射中出現兩次,比如鍵值"o1" "o2")中的值地圖是包含字母的塊列表。
構建此數據結構后,您需要在映射中的值中搜索一組唯一的整數值。
編輯:
所以這些塊已經在數組中表示了。所以第一個塊,其中的塊cubes[0]將有一個 id 值0,依此類推。對于“食物”這個詞,您構建了一個包含四個條目的地圖。鍵是:"f1"、"o1"、"o2"、"d1"。使用這些數字是為了讓您可以在地圖上多次放置同一個字母。
確定鍵后,您將在所有塊上循環,對于每個塊的所有字母,對于您查看的每個字母,如果它是目標單詞的一部分。如果是,則將塊的 id(在 中的索引cubes,還記得嗎?)添加到映射中的值列表中。完成后你將得到以下映射
"f1" -> [0,2,3] // blocks 0,2,3 contain 'f'
"o1" -> [0,1,2]
"o2" -> [0,1,2]
"d1" -> [0,1]
現在你在值(整數列表)上循環并尋找一組從每個映射條目中獲取的唯一整數值。例如集合 3,1,2,0(3 取自第一個地圖條目,1 來自第二個地圖條目,依此類推)-> 集合就是答案。

TA貢獻1877條經驗 獲得超6個贊
String[] split = word.split("");
Set<String> mySet = new HashSet<>(split);
for(int i = 0; i < numberOfCubes; i++) {
//get cube
for(int k = 0; k < 6; k++){
//loop through each value in the cube and try to remove it from the set
set.remove(cube[k]);
}
}
if mySet length = 0; return true;//i.e. cubes can create the word
添加回答
舉報