第一题,用JS实现1000个字符的字符串寻找最大相同子串
第二题,对数组进行排序,先按数组长度排,再按数组内容排
比如A1{1,3,5,7}A2{1,2,3,5,9}A3{1,3,5,8}
排序结果为A2,A3,A1
如何实现?
小弟刚开始学JS,思想都知道,求大牛指导具体代码和优化后算法
第二题,对数组进行排序,先按数组长度排,再按数组内容排
比如A1{1,3,5,7}A2{1,2,3,5,9}A3{1,3,5,8}
排序结果为A2,A3,A1
如何实现?
小弟刚开始学JS,思想都知道,求大牛指导具体代码和优化后算法
var arr1=[[1,2,5,7],[1,2,5,7,9],[2,3,5,6,7],[2,3,5,7,7]];
arr1.sort(function(a,b){
var res=b.length-a.length,min=Math.min(a.length,b.length);
if(min==0){return res}
for(var i=0;i<min;i++){
var c=a.slice(0),d=b.slice(0);
c.sort(function(a,b){return b-a});
d.sort(function(a,b){return b-a});
res+=' || '+(d[i]-c[i]);
};
return eval(res);
});
var res='';
for(var i=0;i<arr1.length;i++){
res+='['+arr1[i]+']\n'
}
alert("排序结果:\n"+res)
arr1.sort(function(a,b){
var res=b.length-a.length,min=Math.min(a.length,b.length);
if(min==0){return res}
var c=a.slice(0),d=b.slice(0);
c.sort(function(a,b){return b-a});
d.sort(function(a,b){return b-a});
for(var i=0;i<min;i++){
res+=' || '+(d[i]-c[i]);
};
return eval(res);
});
<script type='text/javascript'>
var findMaxRepeat = function(a){
var i=0,o={},same=[],pos=0,cur=0,max=[],len=a.length,end=0;
while(a[i]!=undefined){
if(end) break;
if(o[a[i]]){
for(var j=0,k=o[a[i]].length;j<k;j++){
pos = o[a[i]][j];
cur = i;
same = [];
while(a[pos] == a[cur] && pos < i){
if(cur >= len-1) end=1;
same[same.length] = a[pos];
pos++;cur++;
}
max = max.length > same.length ? max : same;
}
}
//记录每个字符出现的位置,方便下次逐个匹配。
o[a[i]] = o[a[i]] || [];
o[a[i]].push(i);
i++;
}
return max.join('');
}
alert(findMaxRepeat("aaaaaaaaaa"));//最差就是1000个重复字符。
alert(findMaxRepeat("csdn的名字就叫csdn的名字你在哪儿啊"));
</script>#2.取巧,<script type='text/javascript'>
var a = [[1,3,5,7],[1,2,3,5,9],[1,3,5,8]];
a.sort(function(h,t){
return h.length < t.length || (h.join('')*1) < (t.join('')*1);
})
alert(a);
</script>
你看不懂最简单的方法就是:alert();哪里不知道是什么意思,就alert一下下。就啥都明白了
基本思想贪婪算法function maxRepeat(str) {
var max = 0;
var index = 0;
var len = str.length;
while(index + max + 1 < len) {
var test = str.substr(index, max + 1);
var test_len = test.length;
if(str.slice(index+1).indexOf(test) > -1) {
max = test_len;
var maxRepeatString = test;
} else {
index++;
}
}
return {max: max, maxRepeatString: maxRepeatString};
}
function getArrByRandom(){
var seed = new Array( 'a','b','c','d','e','f','g','h','i','j','k','m','n','p','Q','r','s','t','u','v','w','x','y','z');
seedlength = seed.length;//数组长度
var a = '';
for (var i=0;i<1000;i++) {
j = Math.floor(Math.random()*seedlength);
a += seed[j];
}
return a;
}
Array.prototype.inArray=function (value){for (var i=0;i<this.length;i++){if (this[i] == value){return true;}}return false};
/*
*功能:从字符串中提取出现重复出现的字符串,并排序[貌似简单的提取标签的功能可以使用]
*参数:a:要查找的字符串;b:要提取的标签最小长度
*/
function getTags(a,b){
var arr=[],arr2=[];
if(b<1){
b=1;
};
for(var i=0;i<a.length;i++){
for(var j=i;j<a.length;j++){
var str=a.substring(i,j),len=a.split(str).length;
if(len>2 && !arr2.inArray(str) && str.length>b-1){
arr2.push(str);
arr.push({chr:str,len:len-1});
}
}
};
//下面是返回按相同字符串的长度进行排序
arr.sort(function(a,b){return b.chr.length-a.chr.length});
//下面是按相同字符串的出现次数进行排序
//arr.sort(function(a,b){return b.len-a.len});
//输出结果查看:
var res='';
for(var i=0;i<arr.length;i++){
res+='['+arr[i].chr+'] 出现 ['+arr[i].len+'] 次\n'
}
document.getElementById('arrsort').value=a+"\n最终排序为:\n"+res;
}
window.onload=function(){
var str=getArrByRandom();
getTags(str,3);
}
</script>
<textarea rows="30" cols="60" style="display:block" id="arrsort"></textarea>1000个字符串就花费了6秒来钟,效率好低下。求优化~~
Good job!!!//不用slice
if(str.indexOf(test,index+1) > -1)
兄弟,我发现你有点OOP的思维定势,有时候回归简单才是王道,呵呵。
var a = [[1, 3, 5, 7], [1, 2, 3, 5, 9], [1, 3, 5, 8]];
a.sort(function (h, t) {
return parseInt(t.join(''))-parseInt(h.join(''));
});
alert(a);
</script>
a.sort(function (a, b) {
var c=a.slice(0),d=b.slice(0);
c.sort(function(a,b){return b-a});
d.sort(function(a,b){return b-a});
return parseInt(d.join(''))-parseInt(c.join(''));
});
<script type='text/javascript'>
function maxRepeat(str) {
var max = 0;
var index = 0;
var len = str.length;
while(index + max + 1 < len) {
var test = str.substr(index, max + 1);
var test_len = test.length;
if(str.slice(index+1).indexOf(test) > -1) {
max = test_len;
var maxRepeatString = test+str.substr(index+1,1);
} else {
index++;
}
}
return maxRepeatString;
}
var a="aaaabbcc";
alert(maxRepeat(a)); </script>
这俩题目现在看来似乎都描述不清,包括第二题,需要明确怎么个叫按内容排,现在有点理解不能,是否有限定每个数组项都是小于10的自然数,我按我那个方法排序,结果就是A2,A3,A1,不过没在ie下测。
#32楼"aaaabbcc"居然返回的是aaaa?不是aa?
题目说的是相同子串,不是连续字符最长的串吧,不过即使这样也没说明是需要'重叠'计算的,还是需要'不重叠'计算的.
我#8楼是按‘不重叠’的找,
比如‘aaaaaaaa’ 8个a,最长的子串我认为是'aaaa',对半分嘛,一个位置不做两次扫描,不过算法实现还有点问题
而#14楼是'重叠'的找
同样8个a,会返回7个a,因为子串{0-6}和子串{1-7}是相同的。 var findMaxRepeat = function(a,t){
var i=0,o={},same=[],pos=0,cur=0,max='',len=a.length,end=0,ret=[],c=t||0;
while(i < len){
if(end) break;
if(o[a[i]]){
for(var j=0,k=o[a[i]].length;j<k;j++){
pos = o[a[i]][j];
cur = i;
same = [];
while(a[pos] == a[cur]){
if(c && (pos > i))
{
i = cur;
break;
}
if(cur >= len-1) end=1;
same[same.length] = a[pos];
pos++;cur++;
}
if(max.length < same.length){
max = same.join('');
ret = [max];
}
if(max.length == same.length && max != same.join('')){
ret[ret.length] = same.join('');
}
}
}
o[a[i]] = o[a[i]] || [];
o[a[i]].push(i);
i++;
}
console.log(o)
return ret;
}
console.log(findMaxRepeat("atatatatat"))//不重叠找
console.log(findMaxRepeat("atatatatat"),1)//重叠找
14楼也是按‘不重叠’的找,不过 if(str.slice(index+max+1).indexOf(test) > -1 疏忽少加一个max。
/**-------------------------
* n1和n2满足如下条件:
* 1. n1 + n2 = sum;
* 2. n1*n1 + n2*n2 = sqSum;
* 用角坐标表示n1、n2后可以将
* 条件合并为: sqrt(sqSum)*sin(z) + sqrt(sqSum)*cos(z) = sum
* 化 简 为 :1 + 2*sin(z)*cos(z) = sum*sum/sqSum
* 化 简 为 :sin(2*z) = (sum * sum)/sqSum - 1
* 所以弧度为:z = Math.asin( (sum * sum)/sqSum - 1)/2
* 所以n1 : Math.floor(Math.sin(sqrt(sqSum) * sin(z)))
* 所以n2 : Math.floor(Math.cos(sqrt(sqSum) * sin(z)))
*-------------------------*/function test(){
//模拟抽取
var a = [];
var max = 100000;
var n1 = Math.floor(Math.random() * (max+1));
var n2 = Math.floor(Math.random() * (max+1));
for(var i=1; i<=max; i++){
if( i != n1 && i != n2 ){
a.push(i);
}
} //计算两数和与平方和
var sum = (max + 1)*(max/2);
var sqSum = max*(max+1)*(2*max+1)/6; //平方和公式: n(n+1)(2n+1)/6
var num;
for(var i=0,len=a.length; i<len; i++){
num = a[i];
sum -= num;
sqSum -= num*num;
} //计算两数
var z = Math.asin(sum*sum/sqSum - 1)/2;
var r = Math.sqrt(sqSum);
var n3= Math.round(r * Math.sin(z));
var n4= Math.round(r * Math.cos(z));
//检验是否通过测试
return [
[n1, n2].sort().join(','),
[n3, n4].sort().join(',')
]
}var i, a;
for(i=0; i<1000; i++){
a = test();
if(a[0] != a[1]){
console.error(i + '\tnot passed test: ' + a);
}
}
arr.sort(function(a,b){return b.length-a.length});
arr.sort(function(a,b){if(a.length==b.length){var i=a.length;for(var j=0;j<i;j++){if(b[j]!=a[j]){return b[j]-a[j];}}}});
function maxRepeat(str, t) {
var max = 0;
var index = 0;
var len = str.length;
while(index + max + 1 +(t? max: 0)< len) {
var test = str.substr(index, max + 1);
var test_len = test.length;
if(str.indexOf(test, t? max+index+1: index+1) > -1) {
max = test_len;
var maxRepeatString = test;
} else {
index++;
}
}
return {max: max, maxRepeatString: maxRepeatString};
}在33楼的提示下,我考虑了重复与非重复的情况,这样就ok了
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title></title>
</head>
<body>
<script type="text/javascript">
+function(){
var arr = [[1,2,3,7],[1,2,3,4,5],[1,2,3,8]];
arr.sort(function(a, b){
return b.length == a.length ? b.join('') - a.join('') : b.length - a.length;
});
document.write(arr.join('<br/>'));
document.write("</br></br>");
}();
+function(){
function makestring(len){
var arr = [];
for(var i = 0; i < len; i++){
arr.push(parseInt(Math.random()*10));
}
return arr.join('');
}
function find(str){
var len = str.length, max = len / 2, i, sub;
while(max > 0){
for(i = 0; i + max * 2 <= len; i++){
sub = str.substr(i, max);
if(str.indexOf(sub, i + max) >= 0){
return {len:max, start:i, text:sub};
}
}
max--;
}
return {len:0};
}
var str = makestring(1000);
var ret = find(str);
var fmt = str.replace(new RegExp("("+ret.text+")", "g"), "<font color='red'>$1</font>").replace(/(\d)/g, "$1 ");
document.write( fmt + '<br/><br/>');
document.write(ret.len + "_" + ret.start + "_" + ret.text + "<br/>");
}();
</script>
</body>
</html>
var input = 'asdkfllajsdf oinpqwj fm,zxj cvioqwuj pofamsn,l;df jaopsiduf jaskl;djf aosiduf askdjf kla;sdjf oiasdjf aslkdfj aosipduf jaskdfj aslkd;fj opaisduf ioasdjf ioasdjf klasdfj asipoduf iopasddjf aklsdjf kaskdhfjkasdhdfjkhqw9uier aksdjfhklajsdfkasdjf opaisue rqowkj eroijsdafk lansddkjfj alskdfj iopasduf klasdjf askl;dfj aiospdfu klxzcvn iuoasou foiargnbkjlsckjghv 8912345rusdai fasjdtuf089q34jrfkjasldfj iasdf 89-23 rasedfj';var test = function(){
for(var subLen = input.length - 1;subLen > 0; subLen-- ){
var max = input.length - subLen;
var array = new Array();
for(var offset = 0; offset < max; offset ++ ){
var str = input.substring(offset,offset + subLen);
for(var i = 0;i<array.length;i++){
if(array[i] === str){
return str;
}
}
array.push(str);
}
}
}alert(test(input));</script>
for(var offset = 0; offset <= max; offset ++ ){
}
更正下.
function ch1(x,y) {
if(x.length>y.length) return 1;
if(x.length<y.length) return -1;
if(x.length == y.length) {
if(Math.max.apply(null,x) > Math.max.apply(y)) return 1;
if(Math.max.apply(null,x) < Math.max.apply(y)) return -1;
return 0;
}
}
function compare(x,y) {
if(x<y) return -1;
if(x>y) return 1;
return 0;
}
aa =aa.sort(ch1);
for(var i=0;i<aa.length;i++) {
aa[i] = aa[i].sort(compare);
}console.log(aa);方法需要优化,但也算实现了
a.sort(function(k,o){return k-o;});
b.sort(function(k,o){return k-o;});
return a.length - b.length;
});//下面的都只是为输出写的了
var rtn="";
for(var i = 0; i < arr1.length;i++){
rtn += ( i==0 ?"":"," ) + "["
var obj = arr1[i];
for(var k = 0; k < obj.length;k++){
rtn += (k == 0 ? "" : ",") +obj[k];
}
rtn += "]";
}window.console.log(rtn);这样不就好了吗?