java 字符串排列组合查找

2023-11-27

我正在写一个Android单词应用程序。我的代码包含一个方法,该方法可以查找字符串和最小长度为 3 的 7 个字母字符串的子字符串的所有组合。然后将所有可用组合与字典中的每个单词进行比较,以找到所有有效单词。我正在使用递归方法。这是代码。

// Gets all the permutations of a string.
void permuteString(String beginningString, String endingString) {
    if (endingString.length() <= 1){
        if((Arrays.binarySearch(mDictionary, beginningString.toLowerCase() +   endingString.toLowerCase())) >= 0){
            mWordSet.add(beginningString + endingString);
        }
    }
    else
        for (int i = 0; i < endingString.length(); i++) {
            String newString = endingString.substring(0, i) + endingString.substring(i + 1);
            permuteString(beginningString + endingString.charAt(i), newString);
      }
}
// Get the combinations of the sub-strings. Minimum 3 letter combinations
void subStrings(String s){
    String newString = "";
    if(s.length() > 3){
        for(int x = 0; x < s.length(); x++){
            newString = removeCharAt(x, s);
            permuteString("", newString);
            subStrings(newString);
        }
    }
}

上面的代码运行良好,但是当我将其安装在 Nexus 上时,我意识到它运行得有点太慢了。需要几秒钟才能完成。大约3或4秒,这是不可接受的。 现在我在手机上玩了一些文字游戏,它们会立即计算出字符串的所有组合,这让我相信我的算法不是很有效并且可以改进。有人可以帮忙吗?


public class TrieNode {
TrieNode a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
TrieNode[] children = {a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z};
private ArrayList<String> words = new ArrayList<String>();

public void addWord(String word){
    words.add(word);
}
public ArrayList<String> getWords(){
    return words;
}
}

public class Trie {

static String myWord;
static String myLetters = "afinnrty";
static char[] myChars;
static Sort sort;
static TrieNode myNode = new TrieNode();
static TrieNode currentNode;
static int y = 0;
static ArrayList<String> availableWords = new ArrayList<String>();

public static void main(String[] args) {

    readWords();
    getPermutations();
}
public static void getPermutations(){
    currentNode = myNode;
    for(int x = 0; x < myLetters.length(); x++){
        if(currentNode.children[myLetters.charAt(x) - 'a'] != null){
            //availableWords.addAll(currentNode.getWords());
            currentNode = currentNode.children[myLetters.charAt(x) - 'a'];
            System.out.println(currentNode.getWords() + "" + myLetters.charAt(x));
        }
    }
    //System.out.println(availableWords);
}
public static void readWords(){
    try {
        BufferedReader in = new BufferedReader(new FileReader("c://scrabbledictionary.txt"));
        String str;
        while ((str = in.readLine()) != null) {
            myWord = str;
            myChars = str.toCharArray();
            sort = new Sort(myChars);
            insert(myNode, myChars, 0);
        }
        in.close();
    } catch (IOException e) {
    }
}
public static void insert(TrieNode node, char[] myChars, int x){    
    if(x >= myChars.length){
        node.addWord(myWord);
        //System.out.println(node.getWords()+""+y);
        y++;
        return;
    }
    if(node.children[myChars[x]-'a'] == null){
        insert(node.children[myChars[x]-'a'] = new TrieNode(), myChars, x=x+1);
    }else{
        insert(node.children[myChars[x]-'a'], myChars, x=x+1);
    }
}
}

在当前的方法中,您正在查找每个子字符串的每个排列。因此对于"abc",你需要查找"abc", "acb", "bac", "bca", "cab" and "cba"。如果你想找到“排列”的所有排列,你的查找次数几乎是500,000,000,那是在您查看其子字符串之前。但我们可以将其简化为one通过预处理字典来查找,无论长度如何。

这个想法是将字典中的每个单词放入某种数据结构中,其中每个元素包含一组字符,以及包含(仅)这些字符的所有单词的列表。例如,您可以构建一个二叉树,其中包含一个包含(排序的)字符集的节点"abd"和单词列表["bad", "dab"]。现在,如果我们想找到所有排列"dba",我们对其进行排序以给出"abd"并在树中查找以检索列表。

正如鲍曼指出的,tries非常适合存储此类数据。 trie 的美妙之处在于查找时间仅取决于搜索字符串的长度- 这是与字典的大小无关。由于您将存储相当多的单词,并且大多数搜索字符串都很小(大多数是来自递归最低级别的 3 字符子字符串),因此这种结构是理想的。

在这种情况下,特里树中的路径将反映字符集而不是单词本身。所以如果你的整个字典是["bad", "dab", "cab", "cable"],您的查找结构最终将如下所示:

Example trie

实现此方法时需要进行一些时间/空间权衡。在最简单(也是最快)的方法中,每个Node仅包含单词列表和一个数组Node[26]孩子的。这使您可以在恒定的时间内找到您正在寻找的孩子,只需查看children[s.charAt(i)-'a'] (where s是您的搜索字符串,并且i是您当前在 trie 中的深度)。

缺点是你的大部分children数组大部分是空的。如果空间是一个问题,您可以使用更紧凑的表示形式,例如链表、动态数组、哈希表等。但是,这些的代价是可能需要在每个节点进行多次内存访问和比较,而不是简单的数组访问上面。但如果整个字典中浪费的空间超过几兆字节,我会感到惊讶,因此基于数组的方法可能是您最好的选择。

使用 trie 后,整个排列函数将被一次查找所取代,从而将复杂性降低O(N!log D) (where D是你的字典的大小,N字符串的大小)到O(N log N)(因为您需要对字符进行排序;查找本身是O(N)).

EDIT:我已经整理了此结构的(未经测试的)实现:http://pastebin.com/Qfu93E80

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java 字符串排列组合查找 的相关文章

  • 为什么 i++ 不是原子的?

    Why is i Java 中不是原子的 为了更深入地了解 Java 我尝试计算线程中循环的执行频率 所以我用了一个 private static int total 0 在主课中 我有两个线程 主题 1 打印System out prin
  • Play框架运行应用程序问题

    每当我尝试运行使用以下命令创建的新 Web 应用程序时 我都会收到以下错误Play http www playframework org Error occurred during initialization of VM Could no
  • Final字段的线程安全

    假设我有一个 JavaBeanUser这是从另一个线程更新的 如下所示 public class A private final User user public A User user this user user public void
  • Android MediaExtractor seek() 对 MP3 音频文件的准确性

    我在使用 Android 时无法在eek 上获得合理的准确度MediaExtractor 对于某些文件 例如this one http www archive org download emma solo librivox emma 01
  • 控制Android的前置LED灯

    我试图在用户按下某个按钮时在前面的 LED 上实现 1 秒红色闪烁 但我很难找到有关如何访问和使用前置 LED 的文档 教程甚至代码示例 我的意思是位于 自拍 相机和触摸屏附近的 LED 我已经看到了使用手电筒和相机类 已弃用 的示例 但我
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Liferay ClassNotFoundException:DLFileEntryImpl

    在我的 6 1 0 Portal 实例上 带有使用 ServiceBuilder 和 DL Api 的 6 1 0 SDK Portlet 这一行 DynamicQuery query DynamicQueryFactoryUtil for
  • 我可以使用 HSQLDB 进行 junit 测试克隆 mySQL 数据库吗

    我正在开发一个 spring webflow 项目 我想我可以使用 HSQLDB 而不是 mysql 进行 junit 测试吗 如何将我的 mysql 数据库克隆到 HSQLDB 如果您使用 spring 3 1 或更高版本 您可以使用 s
  • 路径中 File.separator 和斜杠之间的区别

    使用有什么区别File separator和一个正常的 在 Java 路径字符串中 与双反斜杠相反 平台独立性似乎不是原因 因为两个版本都可以在 Windows 和 Unix 下运行 public class SlashTest Test
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • AWS 无法从 START_OBJECT 中反序列化 java.lang.String 实例

    我创建了一个 Lambda 函数 我想在 API 网关的帮助下通过 URL 访问它 我已经把一切都设置好了 我还创建了一个application jsonAPI Gateway 中的正文映射模板如下所示 input input params
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 如何从指定日期获取上周五的日期? [复制]

    这个问题在这里已经有答案了 如何找出上一个 上一个 星期五 或指定日期的任何其他日期的日期 public getDateOnDay Date date String dayName 我不会给出答案 先自己尝试一下 但是 也许这些提示可以帮助
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 玩!框架:运行“h2-browser”可以运行,但网页不可用

    当我运行命令时activator h2 browser它会使用以下 url 打开浏览器 192 168 1 17 8082 但我得到 使用 Chrome 此网页无法使用 奇怪的是它以前确实有效 从那时起我唯一改变的是JAVA OPTS以启用
  • 如何实现仅当可用内存较低时才将数据交换到磁盘的写缓存

    我想将应用程序生成的数据缓存在内存中 但如果内存变得稀缺 我想将数据交换到磁盘 理想情况下 我希望虚拟机通知它需要内存并将我的数据写入磁盘并以这种方式释放一些内存 但我没有看到任何方法以通知我的方式将自己挂接到虚拟机中before an O
  • 节拍匹配算法

    我最近开始尝试创建一个移动应用程序 iOS Android 它将自动击败比赛 http en wikipedia org wiki Beatmatching http en wikipedia org wiki Beatmatching 两
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分

随机推荐

  • 仅使用 Django 的 DB 部分

    有人知道 Django 有多 模块化 吗 我可以只使用 ORM 部分来获取映射到数据库表的类并知道如何从这些表中读取 写入吗 如果没有 您会推荐什么作为 Hibernate 的 Python 等价物 如果您喜欢 Django 的 ORM 独
  • 如何在Android中的EditText上设置自定义字体?

    我正在尝试在EditText 与我目前正在做的事情相比 有人有更好的方法吗 Typeface myFont Typeface createFromAsset getAssets fonts myfont ttf edittext setTy
  • FSharp 构建在 MSBuild 中失败,但在 Visual Studio 中工作正常

    我的解决方案中有许多项目 其中还有一个 F 项目 在 Visual Studio 中一切都构建得很好 但是当我尝试在 TeamCity 服务器 未安装 VS 上使用 MSBuild 构建它时 它会抛出以下构建错误 C TeamCity bu
  • __callStatic()、call_user_func_array()、引用和 PHP 5.3.1

    我一直在阅读有关 SO 和其他地方的内容 但我似乎找不到任何结论性的东西 是否有任何方法可以有效地通过此调用堆栈携带引用 从而实现如下示例中所述的所需功能 虽然这个例子并没有试图解决它 但它确实说明了问题 class TestClass s
  • 使用滚动中位数过滤 Pandas 数据框中的异常值

    我正在尝试从带有日期的 GPS 高程位移散点图中过滤掉一些异常值 我尝试使用 df rolling 计算每个窗口的中值和标准差 然后如果它大于 3 个标准差则删除该点 但是 我无法找到一种方法来循环该列并比较滚动计算的中值 这是我到目前为止
  • 如何用sed插入包含斜杠的字符串? [复制]

    这个问题在这里已经有答案了 我有一个 Visual Studio 项目 是本地开发的 代码文件必须部署到远程服务器 唯一的问题是它们包含的 URL 这些 URL 是硬编码的 该项目包含 URL 例如 page one 为了使链接在服务器上有
  • H2 DB - 列必须位于分组依据列表中

    我正在使用 H2 DB 访问静态数据库 我有一张桌子 看起来像 COUNTRY STATE CITY LAT LNG COUNTRYID STATEID CITYID Germany Berlin 1 23 1 23 1 1 0 Germa
  • Laravel 以良好的方式从控制器定义默认布局

    我用谷歌搜索了两个小时 但没有找到答案 也许你能帮忙 当我定义在我的控制器 class MyController extends Base Controller public layout layouts default public fu
  • Spark-submit/spark-shell>yarn-client和yarn-cluster模式的区别

    我正在使用 YARN 运行 Spark 从链接 http spark apache org docs latest running on yarn html 我找到了不同纱线模式的解释 即 masterSpark 可以运行的选项 有两种部署
  • 我可以在运行时修改Java方法的字节码吗?

    我正在编写另一个大型java程序的插件 我想在运行时修改java程序的某些java方法的一些字节码 以便能够拦截方法调用 即向方法中注入一些hook代码 有什么办法可以达到这个目的吗 PS 我检查了以下方法 1 更改java程序的类加载器
  • Pandas 从列中可用的列表数据中扩展行

    我在 pandas 中有一个像这样的数据框 column1 column2 a b c 1 d e f 2 g h i 3 预期输出 column1 column2 a 1 b 1 c 1 d 2 e 2 f 2 g 3 h 3 i 3 如
  • 具有自动生成功能的 .NET ORM 解决方案:Subsonic、Castle AR,...?

    我曾经使用自定义数据映射库 目前我正在尝试切换到更广泛的 ORM 解决方案 经过一些实验 我将我的要求细化为以下几点 能够从数据库模式生成可用的类 SQL Server 支持就足够了 支持ActiveRecord模式 以编程方式配置 通过代
  • 为 GGPlot2 直方图中高于 X 值的任何内容创建一个 bin

    Using ggplot2 我想创建一个直方图 其中 X 以上的任何内容都被分组到最终的 bin 中 例如 如果我的大部分分布在 100 到 200 之间 并且我想按 10 进行分类 那么我希望将 200 以上的任何内容分类到 200 中
  • 以编程方式用数组填充数组

    这是创建名为的数组的数组的代码sims通过 for 循环并使用str1 到目前为止我需要定义sims手动长度 等于长度str1 like let sims 四个数组等于四个字str1 如何以编程方式用数组填充模拟人生 var str1 do
  • Sqlite3 - 如何从 csv 导入 NULL 值

    我已将 mysql 表转储为 CSV 在此 CSV 文件中 NULL 值写为 N现在我想将此数据导入到 sqlite 数据库中 但我无法告诉 sqlite N是空值 它将其视为字符串 并且该列值存储为 N 而不是 NULL 谁能指导一下如何
  • 如何使用动态键循环 PHP 对象[重复]

    这个问题在这里已经有答案了 我尝试使用 PHP 解析 JSON 文件 但我现在被困住了 这是我的 JSON 文件的内容 John status Wait Jennifer status Active James status Active
  • 匿名类型

    我有一个Dictionary TKey TValue like Dictionary
  • 如何检测用户鼠标移动的距离?

    我正在尝试检测鼠标移动的距离 以像素为单位 我目前正在使用 document mousemove function event var startingTop 10 startingLeft 22 math Math abs startin
  • 我的虚拟主机上的 Apache 500 内部服务器错误 [已关闭]

    Closed 这个问题需要细节或清晰度 目前不接受答案 我的 Web 应用程序项目位于 media disk1 Projects 中的文件夹中 我想使用 Apache 虚拟主机为他们提供服务http lab 这就是我设置虚拟主机的方式 1
  • java 字符串排列组合查找

    我正在写一个Android单词应用程序 我的代码包含一个方法 该方法可以查找字符串和最小长度为 3 的 7 个字母字符串的子字符串的所有组合 然后将所有可用组合与字典中的每个单词进行比较 以找到所有有效单词 我正在使用递归方法 这是代码 G