如何检查一个单词是否可以用几组字母拼写

时间:2019-08-28 20:45:20

标签: java

这就是我要完成的。想象一下,您有6个侧面块,每个侧面都有一个字母。即{f,e,j,x,s,t},并且您也有一个单词,对于这个示例,可以说单词是“ food”,您将如何检查给出的块是否可以拼写该单词。您在单词中获得的块数至少相同,因此,例如“食物”一词将为您提供至少4个块。

我已经做到了,因此每个块都构成一个仅包含可用字母的对象,例如,对于食品这个单词,它仅包含字母F O或D

String[] split = word.split("");

        for(int i = 0; i < numberOfCubes; i++){
             letterObject.put(Integer.toString(i), new validLetters());
            for(int j = 0; j < split.length; j++){
                for(int k = 0; k < 6; k++){
                    if(cubes[i][k].equalsIgnoreCase(split[j]) && !letterObject.get(Integer.toString(i)).getLetters().contains(split[j])){
                        letterObject.get(Integer.toString(i)).addLetter(split[j]);
                        System.out.println("letter added" + split[j]);
                    }
                }
            }
        }

所以我遇到的问题是如何遍历不同的对象并检查它是否可以拼写单词。我遇到的主要问题是,假设您有4个立方体,并且您正在尝试拼写食物,并且您拥有{f,o,d} {f,o} {o}和{f}这些集合,则可能会拼写但是,如果您仅使用forloop,则会说它不能,因为它将在第一个集合中看到“ f”,然后是“ o”,然后是“ o”,那么它将在第四个集合中找不到d。遍历/强行使用所有不同方式进行循环的最佳方法是什么。

编辑: 这将是一个多维数据集的范例,可以尝试拼出“ FOOD”一词

    static String[][] cubes = {
            {"f", "b", "d", "x", "o", "k"},
            {"e", "b", "o", "d", "q", "o"},
            {"f", "l", "c", "o", "e", "f"},
            {"a", "t", "c", "f", "e", "n"}
    };

上面显示的三重forloop会抛出所有无效字母(即BXK ect),并且还会删除重复项,例如,如果一个多维数据集具有2个类似集合2的O,那么它将所有这些都放入其自己的对象中,该对象放入哈希图中。之后,必须使用它来检查给定的多维数据集是否能够拼写单词。集1({“ f”,“ b”,“ d”,“ x”,“ o”,“ k”})操作后具有F和O,因此可以将其放置在单词填充的第一个空格中食物一词中的F点,也可以将其放置在第二个或第三个插槽中,并附有字母o,但由于每个插槽只能使用一次,所以不能用于拼写“ foo”

3 个答案:

答案 0 :(得分:1)

我不完整的想法如下:将块放置在数组中,其索引用作每个块的唯一ID。然后构建一个列表列表: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个来自第二个地图条目,依此类推)->该集合就是答案。

答案 1 :(得分:1)

我做了大多数人可能认为的暴力手段。本质上,我通过为每个块维护一个独立的索引来依次创建每个可能的单词。然后,我将创建的单词与所需单词进行了比较。我还将打印出构建每次成功的位置。一些额外的开销是我允许使用不同数量的面块。最后,可能有错误。


    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.

答案 2 :(得分:0)

const people = [{
    id: 1,
    name: "Bob",
    available: false
  },
  {
    id: 2,
    name: "Sally",
    available: true
  },
  {
    id: 1,
    name: "Trish",
    available: false
  },
];

const peopleAvailable = people
.filter(people => people.available)    /* filter available people */
.map(person => person.name)            /* map each person to name */ 

console.log(peopleAvailable);