Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我应该如何找到重复的单词序列_Java_Algorithm_Repeat - Fatal编程技术网

Java 我应该如何找到重复的单词序列

Java 我应该如何找到重复的单词序列,java,algorithm,repeat,Java,Algorithm,Repeat,我需要检测多个只给出标题的柱状数据块的存在。除了标题词之外,对数据一无所知,每个数据集的标题词都是不同的 重要的是,目前还不知道每个块中有多少单词,因此也不知道有多少块 同样重要的是,单词表总是相对较短——少于20个 因此,给定一个标题词列表或数组,例如: Opt Object Type Opt Object Type Opt Object Type 确定它完全由重复序列组成的最有效的处理方式是什么: Opt Object Type 它必须是精确匹配,所以我的第一个想法是搜索[1+],寻找与

我需要检测多个只给出标题的柱状数据块的存在。除了标题词之外,对数据一无所知,每个数据集的标题词都是不同的

重要的是,目前还不知道每个块中有多少单词,因此也不知道有多少块

同样重要的是,单词表总是相对较短——少于20个

因此,给定一个标题词列表或数组,例如:

Opt
Object
Type
Opt
Object
Type
Opt
Object
Type
确定它完全由重复序列组成的最有效的处理方式是什么:

Opt
Object
Type
它必须是精确匹配,所以我的第一个想法是搜索[1+],寻找与[0]匹配的项,称它们为索引n,m,。。。然后,如果它们是等距的,则检查[1]=[n+1]=[m+1]和[2]=[n+2]=[m+2]等

编辑:它必须适用于某些单词本身在块中重复的单词集,因此

Opt
Opt
Object
Opt
Opt
Object
这是一套2

Opt
Opt
Object

单位序列能包含自己的重复吗?你知道单位序列的长度吗

e、 g

其中,单元顺序为
abcabcdef

如果答案是肯定的,那么你就遇到了一个难题,我认为,除非你知道单元序列的长度(在这种情况下,解决方案很简单,你只需要创建一个状态机,首先存储单元序列,然后验证序列的每个元素其余部分对应于单元序列的每个元素)

如果答案为“否”,则使用此变量识别装置顺序:

Opt
Object
Type
  • 初始化指向序列开头的指针P1和P2
  • 对于每个新元素,每次递增指针P1,每隔一次递增指针P2(保持一个计数器以执行此操作)
  • 如果P1指向P2的一个相同元素,那么您已经找到了一个单位序列

  • 现在重复序列的其余部分,以验证它是否包含重复项


更新:您已经澄清了问题,说明单元序列可能包含自身的重复。在这种情况下,使用循环查找算法,但只能保证找到潜在的循环。在整个序列中保持运行,并使用以下状态机,从状态1开始:

状态1:未发现有效的循环;继续找。当循环查找算法找到一个潜在循环时,验证您已经从P获得了一个初步单元序列的2个副本,并进入状态2。如果到达输入的末尾,则转到状态4

状态2:发现初步单元序列。只要循环重复相同,就运行输入。如果到达输入的末尾,则转到状态3。如果发现输入元素与单元序列的对应元素不同,请返回状态1

状态3:如果输入端包含单位序列的完整重复,则输入为单位序列的重复。(如果它在单元序列的中间,例如
abcab
,则找到单元序列,但它不包含完整的重复。)

状态4:未找到单元序列


在我的示例中(重复
abcabcdef
),算法首先找到ABCABC,这将使它处于状态2,它将一直停留在那里,直到它到达第一个DEF,这将使它回到状态1,然后可能在状态1和状态2之间来回跳跃,直到它到达第二个abcabcdef,此时它将重新进入状态2,而在输入结束时它将处于状态3。

如果列表由x个重复组组成,每个组包含n个元素

我们知道至少有一个组,所以我们将查看是否有两个重复组,通过比较列表的上半部分和下半部分进行测试

1) 如果以上是真的,我们知道解是一个因子2

2) 如果上面是假的,我们移动到下一个最大的素数,它可以被总字数整除

在每一步中,我们都会检查列表之间是否相等,如果我们找到了,就知道我们有一个包含该因素的解决方案

我们想要返回一个单词列表,对于这些单词,第一个素数的最大因子在子列表中是相等的

因此,我们将上述公式应用于子列表,知道所有子列表都是相等的。。。因此,解决方案最好是递归求解。也就是说,我们只需要孤立地考虑当前的子列表。

该解决方案将是非常有效的,如果加载一个简短的素数表。。。在此之后,有必要计算它们,但如果只考虑几十个素数的列表,那么该列表就必须是非平凡的。

我的解决方案可能很幼稚,它可以按预期工作。它的优点是简单

String[]                            wta;                                    // word text array
...
INTERVAL:
for(int xa=1,max=(wta.length/2); xa<=max; xa++) {
    if((wta.length%xa)!=0) { continue; }                                    // ignore intervals which don't divide evenly into the words
    for(int xb=0; xb<xa; xb++) {                                            // iterate the words within the current interval
        for(int xc=xb+xa; xc<wta.length; xc+=xa) {                          // iterate the corresponding words in each section
            if(!wta[xb].equalsIgnoreCase(wta[xc])) { continue INTERVAL; }   // not a cycle
            }
        }
    ivl=xa;
    break;
    }
String[]wta;//word文本数组
...
间隔时间:

对于(intxa=1,max=(wta.length/2);xa比我的另一个答案更好:一个有效的Java实现,应该简单易懂,并且是通用的:

package com.example.algorithms;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

interface Processor<T> {
    public void process(T element);
}

public class RepeatingListFinder<T> implements Processor<T> {

    private List<T> unit_sequence = new ArrayList<T>();
    private int repeat_count = 0;
    private int partial_matches = 0;
    private Iterator<T> iterator = null;

    /* Class invariant:
     * 
     * The sequence of elements passed through process()
     * can be expressed as the concatenation of
     *        the unit_sequence repeated "repeat_count" times,
     *   plus the first "element_matches" of the unit_sequence.
     * 
     * The iterator points to the remaining elements of the unit_sequence,
     * or null if there have not been any elements processed yet.
     */

    public void process(T element) {
        if (unit_sequence.isEmpty() || !iterator.next().equals(element))
        {
            revise_unit_sequence(element);
            iterator = unit_sequence.iterator();
            repeat_count = 1;
            partial_matches = 0;
        }
        else if (!iterator.hasNext())
        {
            iterator = unit_sequence.iterator();
            ++repeat_count;
            partial_matches = 0;
        }
        else
        {
            ++partial_matches;
        }
    }

    /* Unit sequence has changed. 
     * Restructure and add the new non-matching element. 
     */
    private void revise_unit_sequence(T element) {
        if (repeat_count > 1 || partial_matches > 0)
        {
            List<T> new_sequence = new ArrayList<T>();
            for (int i = 0; i < repeat_count; ++i)
                new_sequence.addAll(unit_sequence);
            new_sequence.addAll(
                    unit_sequence.subList(0, partial_matches));

            unit_sequence = new_sequence;
        }
        unit_sequence.add(element);
    }

    public List<T> getUnitSequence() { 
        return Collections.unmodifiableList(unit_sequence);
    }
    public int getRepeatCount() { return repeat_count; }
    public int getPartialMatchCount() { return partial_matches; }
    public String toString()
    {
        return "("+getRepeatCount()
        +(getPartialMatchCount() > 0 
            ? (" "+getPartialMatchCount()
                +"/"+unit_sequence.size())
            : "")
        +") x "+unit_sequence;
    }

    /********** static methods below for testing **********/

    static public List<Character> stringToCharList(String s)
    {
        List<Character> result = new ArrayList<Character>();
        for (char c : s.toCharArray())
            result.add(c);
        return result;
    }

    static public <T> void test(List<T> list)
    {
        RepeatingListFinder<T> listFinder 
            = new RepeatingListFinder<T>();
        for (T element : list)
            listFinder.process(element);
        System.out.println(listFinder);
    }

    static public void test(String testCase)
    {
        test(stringToCharList(testCase));
    }

    static public void main(String[] args)
    {
        test("ABCABCABCABC");
        test("ABCDFTBAT");
        test("ABABA");
        test("ABACABADABACABAEABACABADABACABAEABACABADABAC");
        test("ABCABCABCDEFABCABCABCDEFABCABCABCDEF");
        test("ABABCABABCABABDABABDABABC");      
    }
}
package com.example.algorithms;
导入java.util.ArrayList;
导入java.util.Collections;
导入java.util.Iterator;
导入java.util.List;
接口处理器{
公共无效过程(T要素);
}
公共类RepeatingListFinder实现处理器{
私有列表单元_序列=新的ArrayList();
私有整数重复计数=0;
private int partial_matches=0;
私有迭代器迭代器=null;
/*类不变量:
* 
*通过进程()的元素序列
*可以表示为
*单元顺序重复“重复计数”次,
*加上单位序列的第一个“元素匹配”。
* 
*迭代器指向unit_序列的其余元素,
*如果没有任何元素,则为null