简体   繁体   English

在元素数组中查找重复的元素系列

[英]Finding repeated series of elements in array of elements

I have an array like this 我有这样的数组

 var randomArray = [1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12] etc..

I can Remove duplicate elements or find duplicate elements in this. 我可以删除重复的元素或在此查找重复的元素。 But I want to log all repeating sequence of elements repeated in array. 但我想记录在数组中重复的所有重复元素序列。 Here is the code I have tried, but it is running into infinite loop 这是我尝试过的代码,但它运行到无限循环中

  for (i = 0; i < randomLength; i++) {
    var cycle = [i],
    flag = 0,
    start = i;
    for (var j = i + 1; j < randomLength; j++) {
       if (randomArray[i] == randomArray[j]) {
         cycle.push(randomArray[j]);
         while (i <= j) {
            if (randomArray[i + 1] == randomArray[j + 1]) {
                cycle.push(randomArray[j + 1]);
            }
            i = i + 1;
            j = j + 1;
         }
         console.log(cycle);
       }
       i = start;
    }
   i = start;
 }  

It should return me. 它应该归还我。 And I don't want to regex to do the same 而且我不想正则表达式做同样的事情

1,2
1,1
10,12

If array is ["a","d","z","e","g","h","a","d","z"]  

then 然后

output would be "a","d","z"

And it should be optimal solution. 它应该是最佳解决方案。 Please suggest me on this. 请建议我这个。 At least corrections to my current code.. 至少更正我当前的代码..

var randomArray = [1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12];

for(var i = 0; i < randomArray.length; i++) {
    var item = randomArray[i];
    var str  = "";    

    while(randomArray[i] == item) {
        str = str + " " + randomArray[i];   
        i++;
    }

    document.write(str + "<br />");
}

See this JSFiddle: http://jsfiddle.net/Ucgtm/ 看到这个JSFiddle: http//jsfiddle.net/Ucgtm/

Here is a solution I just wrote in Haskell. 这是我刚才在Haskell中编写的解决方案。 (You can see how concise the language can be.) Below the code is an example of how it is implemented in the interpreter command line. (您可以看到语言的简洁程度。)下面的代码是一个如何在解释器命令行中实现它的示例。

import Data.List

findSequences list length
  | length >= 2 = repeatedPattern list length ++ findSequences list (length-1)
  | otherwise = []
    where repeatedPattern [] _ = []
          repeatedPattern list size
            | take size list `isInfixOf` drop size list = 
                take size list : repeatedPattern (tail list) size
            | otherwise = repeatedPattern (tail list) size

Prelude> :load "findSequences.hs" Prelude>:加载“findSequences.hs”
[1 of 1] Compiling Main ( findSequences.hs, interpreted ) [1/1]编译Main(findSequences.hs,解释)
Ok, modules loaded: Main. 好的,模块加载:主要。
*Main> let randomArray = [1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12] * Main> let randomArray = [1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12]
*Main> findSequences randomArray (floor $ (/2) $ fromIntegral (length randomArray)) * Main> findSequences randomArray(floor $(/ 2)$ fromIntegral(length randomArray))
[[1,2],[2,1],[1,1],[10,12]] [[1,2],[2,1],[1,1],[10,12]]
*Main> let array = ["a","d","z","e","g","h","a","d","z"] * Main> let array = [“a”,“d”,“z”,“e”,“g”,“h”,“a”,“d”,“z”]
*Main> findSequences array (floor $ (/2) $ fromIntegral (length array)) * Main> findSequences数组(floor $(/ 2)$ fromIntegral(length array))
[["a","d","z"],["a","d"],["d","z"]] [[ “一”, “d”, “Z”],[ “一”, “d”],[ “d”, “Z”]]

I've used a "trie" tree datastructure (google it for more info). 我使用了“trie”树数据结构(谷歌搜索更多信息)。 The tree branches for each sequence. 每个序列的树枝。 It finds 1,1,1 as a solution since 1,1,1 occurs twice. 它找到1,1,1作为解决方案,因为1,1,1发生两次。 (if you want to stop a number being repeated in two sequences, you need to count unique indexes against each node of the trie). (如果要停止以两个序列重复的数字,则需要针对特里结构的每个节点计算唯一索引)。

Here is the code: Runtime should be something like O(N^2) which could be improved on slightly. 这是代码:运行时应该是O(N ^ 2),可以略微改进。

var randomArray = [1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12]

var solve = function(a) {
    var trie = {};
    var sequence_set = {};
    for (var start = 0; start < a.length - 1; start += 1)  {
        var sub_trie = trie[a[start]] || {};
        trie[a[start]] = sub_trie;
        sequence = "" + a[start]
        for (var i = start + 1; i < a.length; i += 1) {
            sequence += "," + a[i]
            sub_trie[a[i]] = sub_trie[a[i]] || {};
            sub_trie = sub_trie[a[i]];
            var sub_trie_count = sub_trie.count || 0;
            sub_trie.count = sub_trie_count + 1;
            if (sub_trie_count >= 1) {
                sequence_set[sequence] = "found";
                console.log(sequence);
            }
        }
    }
    solution = "";
    for (sequence in sequence_set) {
        solution += sequence + ", ";
    }
    console.log(trie)
    return solution;
}

Output: 输出:

1,1 fiddle.jshell.net:37
1,1,1 fiddle.jshell.net:37
1,1 fiddle.jshell.net:37
2,1 fiddle.jshell.net:37
1,2 fiddle.jshell.net:37
10,12 fiddle.jshell.net:37
Object {0: Object, 1: Object, 2: Object, 3: Object, 10: Object, 12: Object, 54: Object}
 fiddle.jshell.net:45

Here is my solution , much like @robert king 's (as I discovered after tackling the problem myself) except mine is complete (already is capable of not counting overlapping patterns) and optimised (as much as I can). 这是我的解决方案 ,就像@robert国王一样(正如我自己解决问题后发现的那样),除了我已经完成(已经能够不计算重叠模式)和优化(尽我所能)。

Also, returns a map of objects, so you can enumerate over it and only pull out patterns of size X, or ones that repeated Y times etc. 此外,返回一个对象的地图,因此你可以枚举它,只能拉出大小为X的图形,或重复Y次的图形等。


The following line (with the below function) 以下行(具有以下功能)

getPatterns([1,2,1,1,1,1,0,2,1,2,3,10,12,54,10,12]).showRepeated();

will result in this; 会导致这个;

1 2 found 2 times
2 1 found 2 times
1 1 found 2 times
10 12   found 2 times


CODE

function getPatterns(input, generateAll) {
    var patternMap = new getPatterns.presentation();

    var generated = [];
    var patternObj;
    var start;
    //for each item
    for (var index = 0; index < input.length; ++index) {
        //open a new slot for a new pattern start at this index
        generated.push('');

        start = 0;
        //unless told to generate all
        //skip patterns that cant possibly be repeated
        //(i.e. longer than half the input length)
        if (!generateAll && generated.length > input.length / 2)
            start = generated.length - Math.floor(input.length / 2);

        //test patterns we have generated for this index
        for (var index2 = start; index2 < generated.length; ++index2) {
            //generate a fresh lot of patterns for this index
            generated[index2] += ' ' + input[index];

            //unless told to generate all, dismiss patterns of length 1
            if (!generateAll && index2 == generated.length - 1)
                break;

            //try to fetch a pre-existing pattern, O(1)
            patternObj = patternMap[generated[index2]];
            //if this is a new pattern
            if (!patternObj) {
                //generate an object
                patternMap[generated[index2]] = {
                    lastSeen : index,
                    count : 1,
                    size : generated.length - index2
                };
                continue;
            }

            //unless told to generate all, skip patterns that overlap with themselves
            if (!generateAll && index - patternObj.lastSeen < patternObj.size)
                continue;

            //this pattern has repeated! update the object data
            ++patternObj.count;
            patternObj.lastSeen = index;
        }
    }

    return patternMap;
}
//just for a function prototype
getPatterns.presentation = function() {};
getPatterns.presentation.prototype = {
    showRepeated : function() {
        var patternObj;
        for (var pattern in this) {
            patternObj = this[pattern];
            if (patternObj.count > 1)
                console.log(pattern + '\tfound ' + patternObj.count + ' times');
        }
    }
};

If you want it in php, it goes like this: 如果你想在PHP中,它是这样的:

Create an array in php outside the <script> <script>之外的php中创建一个数组

$array=array("1","2","2","1".....);

$result = array_unique($array);

Then 然后

var randomArray = <?php echo json_encode($result) ?>;

我认为你的代码可能会遇到无限循环,因为i和j在“while”循环内以相同的速率增加,因此“while”条件不会得到满足。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM