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
添加回答
举报