显示所有非重复组合

时间:2012-09-19 15:32:55

标签: javascript integer combinations

创建一个HTML页面,该页面接受用户在文本字段中的输入,作为非重复整数,长度为3个数字。当用户按下“显示”按钮时,在JavaScript中创建的功能应该能够显示所有6个非重复组合。

示例

输入整数

"123"

该函数应该返回:

"123, 132, 213, 231, 312, 321" 

2 个答案:

答案 0 :(得分:1)

此示例最多可接受12位数字或字母,但我敢打赌,您可以将其调整为仅允许3位数字:

<!doctype html>
<html lang="en">
<head>
<meta charset= "utf-8">
<title>Small Combinations</title>

<style>
form{font-size:1.25em}
fieldset{border:none}
input, button, label, textarea,legend{font-size:inherit; }
input, label{text-align:right; margin:0 1ex; 
background-color:white;color:black;}
button{cursor:pointer}
button:hover, button:focus{color:red}
</style>

<script>
Math.factorial= function(n){
    var i= n;
    while(--i) n*= i;
    return n;
}

//An object containing members and properties of the premutations of a set
function Combos(str){
    if(!(this instanceof Combos)){
        return new Combos(str);
    }
    str= str.replace(/\W+/g, '').toLowerCase();
    var show, deep, def, cf= Combos.diffcoeff(str);
    show= deep= Math.min(cf,5040);
    def={
        coeff: cf, count: 0,
        limit: deep, next: [],
        seed: str.split('').sort().join(''),
        showlimit: show, text: str, items: {}
    }
    for(var p in def) this[p]= def[p];
}
// methods to collect the members
var MP={
    collect: function(s){
        var items= this.items, next= this.next, i, ch= s.split('');
        for(i= 0; i < ch.length; i++){
            next.push(ch.splice(i, 1));
            if(ch.length== 0) items[next.join('')]= 1;
            this.collect(ch.join(''));
            ch.splice(i, 0, next.pop());
        }
    },
    counter: function(){
        var W= this.items, c= 0;
        for(var p in W){
            if(W.hasOwnProperty(p))++c;
        }
        return c;
    },
    //uses timeout to break up long calculation
    getSome: function(){
        if(Combos.quit){
            return Combos.display(this);
        }
        var T= this, items= T.items, n= T.count, max= T.limit,
        ch= this.seed.split(''), next, tick= 2000;
        while(--tick> 0 && n< max){
            next= ch.sort(function(){
                return .5-Math.random()
            }).join('');
            if(!items[next]) items[next]= ++n;
        }       
        T.count= n;
        if(n< max){
            Combos.where.value= n;
            Combos.timer= setTimeout(function(){
                T.getSome()
            },
            0);
        }
        else{
            Combos.timer= setTimeout(function(){
                Combos.display(T)
            },
            0);
        }
    }
}
for(var p in MP)Combos.prototype[p]=MP[p];

//static methods of Combos
var M1={
    //calculate # of permutations
    diffcoeff: function(str){
        var items= {},next,
        members= String(str).split('').sort(), L=members.length;
        for(var i=0;i<L;i++){
            tem=members[i];
            if(!items[tem]) items[tem]= 1;
            else ++items[tem];
        }
        var n= Math.factorial(str.length), g= items;
        for(var p in g){
            if(g.hasOwnProperty(p) && g[p]> 1){
                n/= Math.factorial(g[p]);
            }
        }
        return n;
    },
    // block until complete, set timer to call display
    demo: function(str){
        if(Combos.startTime) return;
        var T= Combos(str);
        Combos.where.value+= '\n';
        Combos.where.ondblclick= function(){
            Combos.quit= true;
        }
        Combos.startTime= +(new Date);
        //limit the number shown- (arbitrary and optional)
        if(str.length> 7) T.getSome()
        else{
            T.collect(T.seed);
            setTimeout(function(){
                T.count= T.counter();
                Combos.display(T);
            },
            0);
        }
    },
    // show results of calculations
    display: function(A){
        var W= [], L, tc= A.count, tm= +(new Date), 
        items= A.items, report= '',
        str= A.text, coeff= A.coeff,
        limit= A.showlimit;

        var tm= ((tm-Combos.startTime)/1000).toFixed(3)+' sec';
        if(limit){
            for(var p in items){
                if(items.hasOwnProperty(p)) W.push(p);
                if(W.length=== limit) break;
            }
        }
        L= W.length;
        report= str+': '+coeff+'  anagrams ';
        if(coeff>= L){
            if(coeff=== tc) report+= ' found ';
            report+= '('+L +' shown)';
            if(coeff> tc) report+= ' found '+tc;
        }
        report+= ' in '+tm+'\n\n'+W.sort().join(', ')+'\n';
        Combos.where.value= report;
        delete Combos.startTime;
        delete Combos.quit;
        Combos.where.ondblclick= '';
        A.elapsed= tm;
        var ins=document.getElementsByTagName('input');
        ins[0].disabled= false;
        ins[0].focus();
        ins[0].select();
    },
    where: ''
}
for(var p in M1)Combos[p]=M1[p];

// page demo, set up event handlers
window.onload= function(){
    var cf, str, show, 
    F= document.forms[0], 
    ins= F.getElementsByTagName('input'),
    btn=F.getElementsByTagName('button')[0],
    btn2=F.getElementsByTagName('button')[1],

    sp=document.getElementById('showcoeff');
    //run on enter
    F.onsubmit=function(){
        btn.onclick();
        return false;// don't actually submit anything
    }
    Combos.where= F.getElementsByTagName('textarea')[0];
    //run on click
    btn.onclick= function(){
        if(Combos.startTime) return;
        str= ins[0].value.replace(/\W+/g, '').toLowerCase();
        if(str){
            sp.firstChild.data=Combos.diffcoeff(str);
            ins[0].value=str;
            Combos.demo(str);
        }
    }
}
</script>
</head>
<body>
<h1>Combinations and Permutations- 1</h1>
<form>
<fieldset>
<legend>Rearranging groups of elements</legend>
<p >
<label>Enter a word or sequence of digits:
<input size="12" maxLength="12" value="123">
</label><button type="submit">Compute</button>
</p>
<p>
</fieldset>
<h3>Unique permutations: <span id="showcoeff">&nbsp;</span></h3>
<textarea cols="80" rows="20" readonly></textarea>
</p>
</form>
</body>
</html>

答案 1 :(得分:0)

这是一个非常简单的版本:http://jsfiddle.net/uXFdZ/

<script type="text/javascript">

    var result = "";

    function perm(s)
    {
        result = "";
        permAux(s, 0);
    }

    function permAux(s, currentPos)
    {
        if (currentPos == s.length-1) //If the index is at the end, it's a unique permutation
            result += (s + "\n");
        else
            for(var k = 0; k < s.length-currentPos; k++) //shifts the characters around k times, each time permutating the substring after the currentPos
                permAux(circularShift(s, currentPos, k), currentPos+1);   
    }

    function circularShift(s, startPos, shiftTimes)
    {
        if (shiftTimes >= s.length)
            shiftTimes %= s.length;

        //first substring takes the substring that will not be shifted, second and third exchange the shifted areas
        return (s.substr(0, startPos) + s.substr(s.length-shiftTimes, shiftTimes) + s.substr(startPos, s.length-shiftTimes-startPos));
    }

    function showResults() {

        var sValue = document.getElementById("number").value;

        var iValue = parseInt(sValue);

        if (isNaN(iValue)) {
            alert("Please enter a number.");
            return;
        }

        perm(sValue);

        alert(result);

}

</script>

<input title="Please Enter a number" id="number" name="number" maxlength="3" />
<button onclick="showResults()">Go</button>

排列代码改编自here