问题描述
比方说0,2,5,6,7,10,12,13,15,18……中,就有5,6,7和12,13两组连续(或更多),则要得到5,6,7的始末位置为(3,5);12,13的始末位置为(7,8)等,如何实现?小弟初学,想到头都破了都想不出,望高手指点,谢谢。
解决方案
解决方案二:
简单的处理思路就是把这些数字放到一个key-value的dictionary中,key存放位置,value存放具体数据,接下来就是写程序判断是否连续了。
解决方案三:
strings="0,2,5,6,7,10,12,13,15,18,21,24.....";strings1=s.Substring(4,5);strings2=s.Substring(13,5);
解决方案四:
看错了:strings="0,2,5,6,7,10,12,13,15,18,21,24.....";stringf="5,6,7";inti=s.IndexOf(f);//起始位置intj=i+f.Length;//结束位置
解决方案五:
下标你用的是1开始的,我习惯用0开始的,也就是(2,4),(6,7)代码是VB的,你看看思路对不对吧。Dimarr=NewInteger(){0,2,5,6,7,10,12,13,15,18}DimIdxStartAsInteger=-1DimIdxEndAsInteger=-1ForiAsInteger=0Toarr.Length-2Ifarr(i)+1=arr(i+1)ThenIfIdxStart=-1ThenIdxStart=iEndIfIdxEnd=i+1ElseIfIdxStart<>-1ThenConsole.WriteLine(String.Format("({0},{1})",IdxStart,IdxEnd))IdxStart=-1EndIfEndIfNextIfIdxStart<>-1ThenConsole.WriteLine(String.Format("({0},{1})",IdxStart,IdxEnd))EndIf
如果讨厌在循环外面还要做处理的话,可以这样做。Dimarr=NewInteger(){0,2,5,6,7,10,12,13,15,18}DimIdxStartAsInteger=-1DimIdxEndAsInteger=-1Dimlst=arr.ToListlst.Add(-1)'在最后增加一个绝不会连续的数字,ForiAsInteger=0Tolst.Count-2Iflst(i)+1=lst(i+1)ThenIfIdxStart=-1ThenIdxStart=iEndIfIdxEnd=i+1ElseIfIdxStart<>-1ThenConsole.WriteLine(String.Format("({0},{1})",IdxStart,IdxEnd))IdxStart=-1EndIfEndIfNext
解决方案六:
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){int[]data={0,2,5,6,7,10,12,13,15,18};List<Tuple<int,int>>result=newList<Tuple<int,int>>();intpre=data[0];intstartidx=0;boolincapture=false;for(inti=1;i<data.Length;i++){if(pre+1==data[i]&&!incapture){incapture=true;startidx=i-1;}if(pre+1!=data[i]&&incapture){incapture=false;result.Add(newTuple<int,int>(startidx,i-1));}pre=data[i];}foreach(variteminresult)Console.WriteLine("{0}~{1}",item.Item1+1,item.Item2+1);}}}
3~57~8请按任意键继续...
解决方案七:
int[]data={0,2,5,6,7,10,12,13,15,18};stringresult=data.Aggregate(new{Lists=Enumerable.Empty<IEnumerable<int>>(),LastData=nullasint?,LastIndex=0},(s,cur)=>s.LastData==null?new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=1}:s.LastData+1==cur?new{Lists=s.Lists.Select(e=>e!=s.Lists.Last()?e:e.Concat(Enumerable.Repeat(s.LastIndex+1,1)).ToArray()).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}:new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(s.LastIndex+1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}).Lists.Where(l=>l.Count()>1).Select(l=>String.Format("{0}->{1}",l.First(),l.Last())).Aggregate((a,b)=>a+Environment.NewLine+b);
自从学了F#,写的代码都像这样了……
解决方案八:
引用6楼iyomumx的回复:
int[]data={0,2,5,6,7,10,12,13,15,18};stringresult=data.Aggregate(new{Lists=Enumerable.Empty<IEnumerable<int>>(),LastData=nullasint?,LastIndex=0},(s,cur)=>s.LastData==null?new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=1}:s.LastData+1==cur?new{Lists=s.Lists.Select(e=>e!=s.Lists.Last()?e:e.Concat(Enumerable.Repeat(s.LastIndex+1,1)).ToArray()).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}:new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(s.LastIndex+1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}).Lists.Where(l=>l.Count()>1).Select(l=>String.Format("{0}->{1}",l.First(),l.Last())).Aggregate((a,b)=>a+Environment.NewLine+b);自从学了F#,写的代码都像这样了……
很久以前,我也用Linq回答过这个问题,被批过代码可读性差。http://bbs.csdn.net/topics/390368137
解决方案九:
引用7楼caozhy的回复:
Quote: 引用6楼iyomumx的回复:
int[]data={0,2,5,6,7,10,12,13,15,18};stringresult=data.Aggregate(new{Lists=Enumerable.Empty<IEnumerable<int>>(),LastData=nullasint?,LastIndex=0},(s,cur)=>s.LastData==null?new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=1}:s.LastData+1==cur?new{Lists=s.Lists.Select(e=>e!=s.Lists.Last()?e:e.Concat(Enumerable.Repeat(s.LastIndex+1,1)).ToArray()).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}:new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(s.LastIndex+1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}).Lists.Where(l=>l.Count()>1).Select(l=>String.Format("{0}->{1}",l.First(),l.Last())).Aggregate((a,b)=>a+Environment.NewLine+b);自从学了F#,写的代码都像这样了……
很久以前,我也用Linq回答过这个问题,被批过代码可读性差。http://bbs.csdn.net/topics/390368137
这是F#改来的:letrecaggratorlistLeftlastIndexlastDatastartIndexaccret=matchlistLeftwith|[]whenstartIndex=lastIndex->accret|[]->accret@[(startIndex,lastIndex)]|(cur&head)::tailwhencur=lastData+1->aggratortail(lastIndex+1)curstartIndexaccret|head::tailwhenlastIndex<>startIndex->aggratortail(lastIndex+1)head(lastIndex+1)(accret@[(startIndex,lastIndex)])|head::tail->aggratortail(lastIndex+1)head(lastIndex+1)accretletaggrl=aggratorl0l.Head0[]
解决方案十:
用linq可读性也好吧。staticvoidMain(string[]args){int[]data={0,2,5,6,7,10,12,13,15,18};//构造一个队列,带上前后元素的值,i:下标,v:元素值,a:前一个值,b:后一个值varmagic=new[]{int.MaxValue};varq=magic.Concat(data).Concat(magic);varq1=q.Zip(q.Skip(1),(a,v)=>new{v,a}).Zip(q.Skip(2),(x,b)=>new{x.v,x.a,b}).Select((x,i)=>new{i,x.v,x.a,x.b});//选出序列的起始元素varqx=q1.Where(x=>x.v-x.a!=1&&x.b-x.v==1);//选出序列的结束元素varqy=q1.Where(x=>x.v-x.a==1&&x.b-x.v!=1);//拼合成想要的下标值对varresult=qx.Zip(qy,(x,y)=>new{x=x.i,y=y.i});foreach(varxinresult){Console.WriteLine("{0}~{1}",x.x,x.y);}}
解决方案十一:
引用8楼iyomumx的回复:
Quote: 引用7楼caozhy的回复:
Quote: 引用6楼iyomumx的回复:
int[]data={0,2,5,6,7,10,12,13,15,18};stringresult=data.Aggregate(new{Lists=Enumerable.Empty<IEnumerable<int>>(),LastData=nullasint?,LastIndex=0},(s,cur)=>s.LastData==null?new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=1}:s.LastData+1==cur?new{Lists=s.Lists.Select(e=>e!=s.Lists.Last()?e:e.Concat(Enumerable.Repeat(s.LastIndex+1,1)).ToArray()).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}:new{Lists=s.Lists.Concat(Enumerable.Repeat(Enumerable.Repeat(s.LastIndex+1,1),1)).ToArray().AsEnumerable(),LastData=curasint?,LastIndex=s.LastIndex+1}).Lists.Where(l=>l.Count()>1).Select(l=>String.Format("{0}->{1}",l.First(),l.Last())).Aggregate((a,b)=>a+Environment.NewLine+b);自从学了F#,写的代码都像这样了……
很久以前,我也用Linq回答过这个问题,被批过代码可读性差。http://bbs.csdn.net/topics/390368137
这是F#改来的:letrecaggratorlistLeftlastIndexlastDatastartIndexaccret=matchlistLeftwith|[]whenstartIndex=lastIndex->accret|[]->accret@[(startIndex,lastIndex)]|(cur&head)::tailwhencur=lastData+1->aggratortail(lastIndex+1)curstartIndexaccret|head::tailwhenlastIndex<>startIndex->aggratortail(lastIndex+1)head(lastIndex+1)(accret@[(startIndex,lastIndex)])|head::tail->aggratortail(lastIndex+1)head(lastIndex+1)accretletaggrl=aggratorl0l.Head0[]
嗯,F#的模式匹配写起来很优雅。赞一个
解决方案十二:
引用9楼jshi123的回复:
用linq可读性也好吧。staticvoidMain(string[]args){int[]data={0,2,5,6,7,10,12,13,15,18};//构造一个队列,带上前后元素的值,i:下标,v:元素值,a:前一个值,b:后一个值varmagic=new[]{int.MaxValue};varq=magic.Concat(data).Concat(magic);varq1=q.Zip(q.Skip(1),(a,v)=>new{v,a}).Zip(q.Skip(2),(x,b)=>new{x.v,x.a,b}).Select((x,i)=>new{i,x.v,x.a,x.b});//选出序列的起始元素varqx=q1.Where(x=>x.v-x.a!=1&&x.b-x.v==1);//选出序列的结束元素varqy=q1.Where(x=>x.v-x.a==1&&x.b-x.v!=1);//拼合成想要的下标值对varresult=qx.Zip(qy,(x,y)=>new{x=x.i,y=y.i});foreach(varxinresult){Console.WriteLine("{0}~{1}",x.x,x.y);}}
不错!
解决方案十三:
如果可直接用data数组,就不用构造队列了,原理一样,代码看上去更省。staticvoidMain(string[]args){int[]data={0,2,5,6,7,10,12,13,15,18};varq=data.Select((v,i)=>new{i,v});varresult=q.Where((x,i)=>(i==0||x.v-data[i-1]!=1)&&i<data.Length-1&&data[i+1]-x.v==1).Zip(q.Where((x,i)=>i>0&&x.v-data[i-1]==1&&(i==data.Length-1||data[i+1]-x.v!=1)),(x,y)=>new{x=x.i,y=y.i});foreach(varxinresult){Console.WriteLine("{0}~{1}",x.x,x.y);}}
解决方案十四:
程序可以写清晰一点。(假设你学习了c#迭代器)可以写usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;namespaceConsoleApplication1{classProgram{staticvoidMain(string[]args){vararr=newint[]{0,2,5,6,7,10,12,13,15,18,19,21,22,23,24,25,17,29,30};varresult=查找连续数字(arr).ToList();foreach(varrinresult)Console.Write("({0},{1})",r.Item1,r.Item2);Console.WriteLine("rn其中长度不小于3的是:");varquery=fromrinresultwherer.Item2-r.Item1+1>=3selectr;foreach(varrinquery)Console.Write("({0},{1})",r.Item1,r.Item2);Console.Write("rn按任意键结束......");Console.ReadKey();}privatestaticIEnumerable<Tuple<int,int>>查找连续数字(int[]arr){varstart=0;while(start<arr.Length-1){varend=查找结束位置(arr,start);if(end!=start)yieldreturnnewTuple<int,int>(start+1,end+1);start=end+1;}}privatestaticint查找结束位置(int[]arr,intstart){for(varj=start+1;j<arr.Length;j++)if(arr[j-1]+1!=arr[j])returnj-1;returnarr.Length-1;}}}
解决方案十五:
由于中间的Tuple<int,int>数据结构,并且需要start=end-1;
之类的语句,仅使用一条linq查询确实是不容易写清晰算法的。c#完全写出成文自明的算法程序,并且很符合一般程序员的表达方式习惯(而不是F#那种方式)。
解决方案:
嗯,有个+号写成了-号了。呵呵我不认为F#语言有多大好处的!在F#刚出来的时候,我倒是感兴趣过一阵。结果发现它跟古老Prolog等相比都差得太远,在基本机制上缺乏古老的函数式工具所同时具有的一些人工智能程序自动回溯机制。我不会“放弃VB.NET之类的话”,因为它是.net平台很好的“编程体验”,对于c#程序员来说也是很好的补充。但是我觉得“可以坚决放弃F#”,因为它确实是多出来太多的累赘(我已经根本不相信F#有可能具有回溯机制机制了)。
解决方案:
该回复于2014-10-04 09:42:17被版主删除
解决方案:
该回复于2014-10-04 09:42:53被版主删除
解决方案:
该回复于2014-10-04 09:42:34被版主删除
解决方案:
该回复于2016-02-28 23:37:06被版主删除
解决方案:
解决方案:
抱歉没看各位大神的代码,我只是简单思考了思路既然是连续,那就是差值=1做一个结构,保存a,a+1的差值结果就会类似2,2,-4,1,1,1,0,-9任何连续的1就是你要的东西了至于语法,一直没兴起学习新东西,一直用简单的for好了各位谈论的语法,包括Linq在内,是不是在原始实现阶段也是各种for?我没细心看过,不对请喷我,我就知道了
解决方案:
该回复于2014-10-04 21:53:42被版主删除
解决方案:
引用21楼xiaobingking的回复:
抱歉没看各位大神的代码,我只是简单思考了思路既然是连续,那就是差值=1做一个结构,保存a,a+1的差值结果就会类似2,2,-4,1,1,1,0,-9任何连续的1就是你要的东西了
之前是查找连续+1的,你给变为查找连续为1的,虽然你变换了问题,但是你解决了问题了吗?只是变换问题,而仍然没有拿出解决问题的算法,这不算是啥解题。不要把你的技术停留在“变换人家的问题”这个层面上,你自己提出的简单问题要每一次都到完全解决问题。
解决方案:
噢噢还有这等热闹的贴,哈哈,不错.比起旁边游戏广告一个可爱女孩给老头一串冰糖葫芦更有吸引力.int[]data={11,12,2,4,5,6,11,12,2,4,5,6};intt=0;stringaa="";boolbb=false;do{if(data[t+1]-data[t]==1){if(!bb)aa+=t.ToString()+",";bb=true;}elseif(bb){aa+=t.ToString()+";";bb=false;}}while(++t<data.Length-2);if(bb)aa+=(t+1).ToString()+";";
做个按思路简单的写法应该比较好理解
解决方案:
比如说为什么会考虑先决策要使用Tuple<int,int>数据结构,然后才写程序?为什么不是随便弄个引用19楼cattpon的回复:
这是大学题目吗?
差不多。这是编程语言课程上的题目。编程语言在软件专业来说,不算是任何一种很高级的基础理论课,只能算是一种职业技能。软件专业有几十门基础理论课,那些课程中的题目才算是“大学题目”。如果这这可题目有什么“大学题目”内容,让我来说,我觉得决策使用中间数据结构Tuple<int,int>是个体现了程序素质的考试点(首先考虑在选择数据结构上尽量规范和可扩展),这可以看出程序员在写一个程序时其实内心里边已经有了想为10倍的“将来应用”留余地的打算。
解决方案:
为什么不是随便弄个字符串之类的?编程语言课程只能算是一种职业技能课程,如果大学生缺乏一大堆其它基础课程的锻炼,那么仅凭学点编程语言培训,是很不够的。
解决方案:
该回复于2014-10-04 22:44:58被版主删除
解决方案:
int[]rdn={0,2,5,6,7,10,12,13,15,18};//这个问题和sql中的取连续数字的问题类似//上面数组中的每一项和它的索引相减会得到一个值//如果值是连续的,那么和索引相减得到的值是相同的,这个值成为分组因子//下面的Select是为了获取每一项的索引,因为GroupBy无法获取每一项的索引vargp=rdn.Select((num,index)=>new{Num=num,Index=index}).GroupBy(pair=>pair.Num-pair.Index);foreach(varitemingp){if(item.Count()<=1)continue;//最小索引Console.Write("{{{0},",item.Min(pair=>pair.Index));//最大索引Console.Write("{0}}}",item.Max(pair=>pair.Index));Console.WriteLine();}
相关处可见《MicrosoftSQLSERVER2005技术内幕:T-SQL查询》的"数字辅助表,已有范围"章节
解决方案:
引用28楼xinzhuu的回复:
int[]rdn={0,2,5,6,7,10,12,13,15,18};//这个问题和sql中的取连续数字的问题类似//上面数组中的每一项和它的索引相减会得到一个值//如果值是连续的,那么和索引相减得到的值是相同的,这个值成为分组因子//下面的Select是为了获取每一项的索引,因为GroupBy无法获取每一项的索引vargp=rdn.Select((num,index)=>new{Num=num,Index=index}).GroupBy(pair=>pair.Num-pair.Index);foreach(varitemingp){if(item.Count()<=1)continue;//最小索引Console.Write("{{{0},",item.Min(pair=>pair.Index));//最大索引Console.Write("{0}}}",item.Max(pair=>pair.Index));Console.WriteLine();}相关处可见《MicrosoftSQLSERVER2005技术内幕:T-SQL查询》的"数字辅助表,已有范围"章节
另类作法,不错
解决方案:
该回复于2014-10-05 02:27:01被版主删除
解决方案:
引用28楼xinzhuu的回复:
int[]rdn={0,2,5,6,7,10,12,13,15,18};//这个问题和sql中的取连续数字的问题类似//上面数组中的每一项和它的索引相减会得到一个值//如果值是连续的,那么和索引相减得到的值是相同的,这个值成为分组因子//下面的Select是为了获取每一项的索引,因为GroupBy无法获取每一项的索引vargp=rdn.Select((num,index)=>new{Num=num,Index=index}).GroupBy(pair=>pair.Num-pair.Index);foreach(varitemingp){if(item.Count()<=1)continue;//最小索引Console.Write("{{{0},",item.Min(pair=>pair.Index));//最大索引Console.Write("{0}}}",item.Max(pair=>pair.Index));Console.WriteLine();}相关处可见《MicrosoftSQLSERVER2005技术内幕:T-SQL查询》的"数字辅助表,已有范围"章节
这段代码有个错误,它不能区分起止数值符合“值减索引相同”的特征,但中间不连续的情况,比如:{1,5,3}
解决方案:
之前没认真看其他人的,今天看了看居然和5#差不多使用结构?那是一样的易如反掌.
解决方案:
引用23楼sp1234的回复:
Quote: 引用21楼xiaobingking的回复:
抱歉没看各位大神的代码,我只是简单思考了思路既然是连续,那就是差值=1做一个结构,保存a,a+1的差值结果就会类似2,2,-4,1,1,1,0,-9任何连续的1就是你要的东西了之前是查找连续+1的,你给变为查找连续为1的,虽然你变换了问题,但是你解决了问题了吗?只是变换问题,而仍然没有拿出解决问题的算法,这不算是啥解题。不要把你的技术停留在“变换人家的问题”这个层面上,你自己提出的简单问题要每一次都到完全解决问题。
之前题目中,都是变数,是一无法确定要找什么,不能if判断我把查找变数,变成固定数值1,这样就可以用判断来寻找了吧只要有一个1就说明至少有一个联系。之前没写明白,我以为那之后的大家都会理解,看来我错了。一般解题的时候,我都是用最原始的思考方式,是因为,关于数学的那些,都没学好,什么结构的,也不会,所以我就用最原始的方法思考,即便是多循环几圈,也没什么吧,能抓到耗子就是好猫。
解决方案:
上边打错字了,修正之前题目中,都是变数,所以无法确定要找什么,不能if判断我把查找的变数,变成固定数值1,这样就可以用判断来寻找了吧只要有一个1就说明至少有一个连续。之前没写明白,我以为那之后的大家都会理解,看来我错了。一般解题的时候,我都是用最原始的思考方式,是因为,关于数学的那些,都没学好,什么结构的,也不会,所以我就用最原始的方法思考,即便是多循环几圈,也没什么吧,能抓到耗子就是好猫。
解决方案:
该回复于2016-02-28 23:37:06被版主删除
解决方案:
该回复于2014-10-05 12:54:00被版主删除
解决方案:
该回复于2014-10-05 12:53:37被版主删除
解决方案:
解决方案:
引用31楼jshi123的回复:
Quote: 引用28楼xinzhuu的回复:
int[]rdn={0,2,5,6,7,10,12,13,15,18};//这个问题和sql中的取连续数字的问题类似//上面数组中的每一项和它的索引相减会得到一个值//如果值是连续的,那么和索引相减得到的值是相同的,这个值成为分组因子//下面的Select是为了获取每一项的索引,因为GroupBy无法获取每一项的索引vargp=rdn.Select((num,index)=>new{Num=num,Index=index}).GroupBy(pair=>pair.Num-pair.Index);foreach(varitemingp){if(item.Count()<=1)continue;//最小索引Console.Write("{{{0},",item.Min(pair=>pair.Index));//最大索引Console.Write("{0}}}",item.Max(pair=>pair.Index));Console.WriteLine();}相关处可见《MicrosoftSQLSERVER2005技术内幕:T-SQL查询》的"数字辅助表,已有范围"章节
这段代码有个错误,它不能区分起止数值符合“值减索引相同”的特征,但中间不连续的情况,比如:{1,5,3}
不太明白
解决方案:
引用39楼xinzhuu的回复:
不太明白
意思是这种方法行不通,比如用{1,5,3}测试,得到结果是(1,3},但实际上没有连续的数列。
解决方案:
Linq中的Aggregate即可完成,楼主可以了解下此方法特性
解决方案:
该回复于2014-10-06 10:23:17被版主删除
解决方案:
不就是一个循环吗?(判断相邻元素递增)
解决方案:
该回复于2014-10-06 10:22:52被版主删除
解决方案:
如果没有计算机,让你找,你会怎么做
解决方案:
解决方案:
该回复于2014-10-06 10:22:34被版主删除
解决方案:
该回复于2014-10-06 10:22:10被版主删除
解决方案:
该回复于2014-10-06 10:21:52被版主删除