当前位置:编程学习 > C#/ASP.NET >>

Foreach如何实现反向遍历啊

string str = "china";
foreach (char c in str)
{
   Trace.WriteLine(c);
}
打印出的结果是:
c
h
i
n
a

不过我想得到反向的遍历结果:
a
n
i
h
c

这个应该如何实现??(不要说先把str排反序,我就是想知道在不调整字符串顺序的前提下,如何反向遍历。。也不要说用for来遍历),只用foreach实现 --------------------编程问答--------------------
          string str = "china";
            for (int i = str.Length-1; i >= 0; i--)
            {
                Console.WriteLine(str[i]);
            }   
或者反转
 char[] cTest = str.ToCharArray();
            Array.Reverse(cTest);
--------------------编程问答-------------------- 好吧,我没有看清楼上主的问题,请无视…… --------------------编程问答-------------------- 写个类继承string,重写GetEnumerator方法。 --------------------编程问答-------------------- 照楼主的要求不能实现,仔细看一下foreach的定义吧:
foreach语句特别适合对集合对象的存取。可以使用该语句逐个提取集合中的元素,并对集合中的每个元素执行语句序列中的操作。
foreach(类型 标识符 in 表达式)

    语句序列
} --------------------编程问答--------------------
引用 3 楼 ariesget 的回复:
写个类继承string,重写GetEnumerator方法。


忘说了,我也不想重写类 --------------------编程问答-------------------- 这个真的就没办法实现了吗?如何在不重写类的前提下重写迭代器接口呢? --------------------编程问答-------------------- foreach语句本身是不可以实现顺序操作的,它的操作是集合对象的顺序。 --------------------编程问答--------------------
引用 7 楼 qq542369628 的回复:
foreach语句本身是不可以实现顺序操作的,它的操作是集合对象的顺序。


哦,那如何在不定义新类的前提下重写迭代器接口呢 --------------------编程问答--------------------
引用 8 楼 joyoyang 的回复:
引用 7 楼 qq542369628 的回复:foreach语句本身是不可以实现顺序操作的,它的操作是集合对象的顺序。

哦,那如何在不定义新类的前提下重写迭代器接口呢

没办法,除非叫写Framework的人重写然后发布新版本。刚看了下貌似string类是sealed的还不能继承。 --------------------编程问答-------------------- 用foreach是不可能实现你的要求的。 --------------------编程问答-------------------- 你想让汽车横着开,又不想自己重新设计。真难为人,庸人自扰 --------------------编程问答--------------------
引用 11 楼 wddw1986 的回复:
你想让汽车横着开,又不想自己重新设计。真难为人,庸人自扰


你不庸 说话给自己留条后路 免得日后被爆菊
我只是问问有没有这样的实现方法,没有的话就算了 --------------------编程问答-------------------- g:\kkk\kkk\bin\Debug>kkk.exe

aa:
0       1       2       3       4       5       6       7       8

reverse   aa:
8       7       6       5       4       3       2       1       0

aa
0       1       2       3       4       5       6       7       8
g:\kkk\kkk\bin\Debug>

using System;
using System.Linq;

namespace kkk
{
    class Program
    {
        static void Main(string[] args)
        {
            int[] aa = Enumerable.Range(0, 9).ToArray();
            Console.WriteLine("\naa:");
            foreach (var bb in aa) Console.Write(bb + "\t");
            Console.WriteLine("\n\nreverse   aa:");
            foreach (var bb in aa.Reverse()) Console.Write(bb + "\t");
            Console.WriteLine("\n\naa");
            foreach (var bb in aa) Console.Write(bb + "\t");
        }
    }
}
--------------------编程问答--------------------
引用 13 楼 CandPointer 的回复:
g:\kkk\kkk\bin\Debug>kkk.exe

aa:
0       1       2       3       4       5       6       7       8

reverse   aa:
8       7       6       5       4       3       2       1       0
……


不用Linq是因为我是.net2.0 --------------------编程问答-------------------- 一个不行吧,好比想在foreach里修改数组一样。让汽车在天上开的感觉。用for吧 --------------------编程问答-------------------- 改Trace.WriteLine(c);
Trace WriteLine里以栈的 形式输出 --------------------编程问答--------------------
引用 15 楼 wwwww112233 的回复:
一个不行吧,好比想在foreach里修改数组一样。让汽车在天上开的感觉。用for吧


实在不行就只能for了 --------------------编程问答--------------------
引用 16 楼 gp55_ 的回复:
改Trace.WriteLine(c);
Trace WriteLine里以栈的 形式输出


输出不是关键,我就是想在迭代的时候从后往前 --------------------编程问答-------------------- 你到底为何要这样做? --------------------编程问答-------------------- --------------------编程问答-------------------- 不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
        public void Start()
        {
            string s = "china";
            foreach (var c in GetReversedEnumerator(s))
            {
                Console.WriteLine(c);
            }

        }
        public  IEnumerable<char> GetReversedEnumerator( string source)
        {
            if (source == null)
                throw new ArgumentNullException();

            for (int i = source.Length - 1; i >= 0;i-- )
            {
                yield return source[i];
            }
        }

如果用.NET3.5GetReversedEnumerator可以实现为扩展方法,使用更方便。

如果想要更通用(又没有.net3.5),可以象LINQ那样自己实现一个对任何IEnumerable都适用的迭代器。
这个类的实现就比上面特别针对string的反序迭代器要麻烦一些了,要针对不同的类型做特别的优化。 --------------------编程问答--------------------
引用 21 楼 hhddzz 的回复:
不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
C# code?12345678910111213141516171819        pub……

这种跟将反序str没啥差别吧。。。按楼主的意思估计也不行。。 --------------------编程问答--------------------
g:\kkk\kkk\bin\Debug>kkk
!dlrow olleH----
Hello world!
g:\kkk\kkk\bin\Debug>



using System;
using System.Collections;

namespace kkk
{
    static class eee
    {
        public static IEnumerable RsForeach(this string src) { return new pss(src); }
        class pss : IEnumerable, IEnumerator
        {
            string src; int pos = -1; public pss(string s) { src = s; pos = s.Length; }
            IEnumerator IEnumerable.GetEnumerator() { return this; }
            bool IEnumerator.MoveNext() { pos--; return (pos >= 0); }
            void IEnumerator.Reset() { pos = src.Length; }
            object IEnumerator.Current { get { return src[pos]; } }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            string hhh = "Hello world!";
            foreach (var ss in hhh.RsForeach()) Console.Write(ss);
            Console.WriteLine("----");
            foreach (var ss in hhh) Console.Write(ss);
        }
    }
}
--------------------编程问答--------------------
引用 23 楼 CandPointer 的回复:
g:\kkk\kkk\bin\Debug>kkk
!dlrow olleH----
Hello world!
g:\kkk\kkk\bin\Debug>



C# code?12345678910111213141516171819202122232425262728using System;using System.Collections; namespace kkk{    s……


g:\kkk\kkk\bin\Debug>kkk
!dlrow olleH
----
Hello world!
g:\kkk\kkk\bin\Debug>


Console.WriteLine("\n----"); --------------------编程问答--------------------
引用 21 楼 hhddzz 的回复:
不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
C# code?12345678910111213141516171819        pub……


这是正解。

string str = "china";
foreach (char c in str.Reverse())
{
   Trace.WriteLine(c);
}

当然,如果你希望效率更高,那么可以实现一个自己的迭代器。
--------------------编程问答--------------------
引用 25 楼 caozhy 的回复:
引用 21 楼 hhddzz 的回复:不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
C# code?123456789101112131415……


LZ 的 #14 , .net 2.0 ,不要Linq --------------------编程问答-------------------- 为什么要纠结在这个问题上呢 --------------------编程问答--------------------
引用 26 楼 CandPointer 的回复:
引用 25 楼 caozhy 的回复:引用 21 楼 hhddzz 的回复:不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
C# code?12……


Linq并不是一种神奇的技术,它就是很普通的一组函数。所以不存在什么.NET 2.0不能用Linq。

lz可以直接使用LinqBridge,一个把Linq函数全部在.NET 2.0中实现的类。 --------------------编程问答-------------------- 追求效率还是用for好了,干嘛纠结这种问题。
去钓鱼岛可以坐船,可以坐飞机,非得骑自行车去干啥 --------------------编程问答-------------------- 你到底想要干吗? --------------------编程问答--------------------
引用 3 楼 ariesget 的回复:
写个类继承string,重写GetEnumerator方法。


string 不能继承 --------------------编程问答--------------------

string 不能继承, 可以 扩展方法,  
top level static class 内, 函数  static xxx(this string) --------------------编程问答--------------------
引用 32 楼 CandPointer 的回复:
string 不能继承, 可以 扩展方法,  
top level static class 内, 函数  static xxx(this string)


是的,不过VS2005/C# 2.0同样不支持扩展方法。使用过时的开发工具和平台,就是自己找麻烦。 --------------------编程问答-------------------- 不可能实现,除非用索引号,用for循环,从大到小。 --------------------编程问答-------------------- LZ关键要明白一点,foreach很多时候使用“迭代器”进行迭代。
而string之所以能够用于foreach,是因为它提供了默认的迭代器。

引用 26 楼 CandPointer 的回复:
引用 25 楼 caozhy 的回复:引用 21 楼 hhddzz 的回复:不需要继承string或者“重写”string的某个成员,你只要有一个能够倒序遍历string的迭代器就行了。
如果你用.NET3.5,LINQ的扩展方法集中自带一个Reverse函数,得到一个IEnumerabe<T>的反序包装。
否则的话,你可以自己实现一个,比如:
C# code?12……

我的代码中并不涉及到LINQ,yield是C#2.0就支持的。 --------------------编程问答-------------------- 你虽然不能更改string类型来更改这个默认的迭代器,但你可以使用完全使用另外一个迭代器来迭代string。 --------------------编程问答-------------------- 编译器对string的foreach迭代是否是使用迭代器 这一点有待考证。
foreach是一种语法,编译器并不一定是使用迭代器来实现,比如对sz数组的迭代编译器就是直接通过索引访问,虽然sz数组实现了IEnumerable接口。
但这不影响显式使用另外一个迭代器来迭代string。 --------------------编程问答-------------------- 越看越蛋疼,什么需求啊?何苦呢? --------------------编程问答--------------------
引用 22 楼 ariesget 的回复:
这种跟将反序str没啥差别吧。。。按楼主的意思估计也不行。。
C# code?123456789101112131415……

这个差别大了,反序str是更改原始数据;
而迭代器是封装迭代逻辑,并不更改数据本身。 --------------------编程问答-------------------- LZ的需求吊爆了。。 --------------------编程问答--------------------
引用 9 楼 ariesget 的回复:
引用 8 楼 joyoyang 的回复:引用 7 楼 qq542369628 的回复:foreach语句本身是不可以实现顺序操作的,它的操作是集合对象的顺序。

哦,那如何在不定义新类的前提下重写迭代器接口呢
没办法,除非叫写Framework的人重写然后发布新版本。刚看了下貌似string类是sealed的还不能继承。


可以扩展 --------------------编程问答-------------------- 重写迭代器吧 --------------------编程问答--------------------    重 写 迭 代 器 --------------------编程问答--------------------
string str = "china";
            string newStr = "";
            foreach (char c in str)
            {
                newStr = c + "\n" + newStr;
            }
            Trace.WriteLine(newStr);
--------------------编程问答-------------------- 这个应该是不行的 --------------------编程问答-------------------- var ar = str.ToCharArray();
for(int i= ar.Length -1;i>=0;i--)
  print(ar[i]); --------------------编程问答-------------------- 陪你无聊一下:



        string str = "china";
        int count = str.Length - 1;
        foreach (char c in str)
        {
            Console.WriteLine(str[count - str.IndexOf(c)]);
        }

--------------------编程问答-------------------- 便利前,对string作反向处理,或者你写入到队列中后,反向读取队列在打印,如果考虑到性能,继承并重写string的 GetEnumerator的事件 --------------------编程问答-------------------- 这2B楼主,这个不行那个不行,要么自己把要求一次说完,要么自己写,别人写出来了又说这个不行,我就草了 --------------------编程问答-------------------- 用索引器不就完事了,搞的这么复杂... --------------------编程问答--------------------
引用 47 楼 N_IThero 的回复:
陪你无聊一下:


C# code?123456        string str = "china";        int count = str.Length - 1;        foreach (char c in str)        {            Console.WriteLine(str[count - str.IndexOf(c)……


楼主正解在这里,你可以给分了,搞的跟我们是给你打工的一样,谦虚点不行? --------------------编程问答-------------------- 除 --------------------编程问答-------------------- 纠结在这个问题上,我看没啥意义,有这功夫还不如研究设计模式呢。 --------------------编程问答-------------------- 哎,不要过于纠结....

反转,排序,for循环都能用

程序是死的,人是活的 --------------------编程问答-------------------- 这需求真奇葩 --------------------编程问答-------------------- 其实很简单。就把字符串翻转一下就可以了
--------------------编程问答-------------------- 真尼玛无聊的问题,用个for会死啊 --------------------编程问答-------------------- 一个很SB的做法,希望能复合你的要求~!!哈哈

        static void Main(string[] args)
        {
            string str = "china";
            int i = 0;
            int j = str.Length;
         ag:   
            foreach (char c in str)
            {
                i++;
                if (i == j)
                {
                    Console.WriteLine(c);    
                    j--;
                    i = 0;
                    goto ag;       
                }
            }
            Console.ReadLine();
        }

--------------------编程问答-------------------- 楼主没事找抽,我估计你们的回复他基本上看不懂。 --------------------编程问答-------------------- 什么奇怪的需求都有啊!!呵呵 自己用 for语句实现吧 --------------------编程问答-------------------- 无法实现,根本不是引进foreach关键字的初衷。 --------------------编程问答--------------------
你不庸 说话给自己留条后路 免得日后被爆菊
 我只是问问有没有这样的实现方法,没有的话就算了 

楼猪看来也不是什么好鸟!! --------------------编程问答-------------------- 来开下眼界,呵呵! --------------------编程问答-------------------- foreach是迭代器,默认情况下只能按原有集合的顺序遍历集合,因为实现IEenumator接口的类的访问方式就和只能向前访问的游标一下,只能不断向下访问,而不能回归访问。 --------------------编程问答--------------------

string str = "China";
int length = str.Length;
foreach (char c in str)
{
      length--;
      Console.WriteLine(str[length]);
}


楼主,这个可以吧! --------------------编程问答--------------------

 string[] list = new string[]{"h","a","c","d","b"};
            StringBuilder sb = new StringBuilder();
            foreach (var c in list)
            {
               sb.Insert (0,string.Format ("\n{0}",c));
            }
            Console.WriteLine(sb.ToString());

--------------------编程问答-------------------- 脑筋急转弯的题目吧?
string s;
foreach (char c in str)
{
    s = c + "\r\n" + s;
}
Trace.Write(s);
--------------------编程问答--------------------
引用 7 楼 qq542369628 的回复:
foreach语句本身是不可以实现顺序操作的,它的操作是集合对象的顺序。
是的 --------------------编程问答-------------------- 看看有没有高深 的武功,,,, --------------------编程问答-------------------- --------------------编程问答--------------------
引用 3 楼 ariesget 的回复:
写个类继承string,重写GetEnumerator方法。

虽然不会c#,但是,我还是知道string是不能继承的。 --------------------编程问答-------------------- 其实把脑袋柱地、双脚举起,就行了! --------------------编程问答-------------------- 这年头“钓丝” 越来越不稀奇了,哈~~~ --------------------编程问答-------------------- CSDN首页上总是一些无聊的问题,劝他他还跟你吹鼻子瞪眼 --------------------编程问答--------------------
引用 72 楼 sp1234 的回复:
其实把脑袋柱地、双脚举起,就行了!


很独特的解决方法 --------------------编程问答-------------------- 根据你说的,不能实现。 --------------------编程问答-------------------- 刚在写as3程序,看到了写下:

string str = "china";
string result;
foreach(char c in str){
  result = c+"\n"+result;
}
Console.WriteLine(result); --------------------编程问答--------------------
引用 44 楼 senliu1506 的回复:
C# code?1234567string str = "china";            string newStr = "";            foreach (char c in str)            {                newStr = c + "\n" + newStr;            }            Trac……
 和你写的一样了,看来不是撸主需要的 --------------------编程问答--------------------
引用 62 楼 binjie1225 的回复:
你不庸 说话给自己留条后路 免得日后被爆菊
 我只是问问有没有这样的实现方法,没有的话就算了 

楼猪看来也不是什么好鸟!!
我也觉得 --------------------编程问答--------------------
引用 79 楼 so_while 的回复:
Quote: 引用 62 楼 binjie1225 的回复:

你不庸 说话给自己留条后路 免得日后被爆菊
 我只是问问有没有这样的实现方法,没有的话就算了 

楼猪看来也不是什么好鸟!!
我也觉得

楼主在家被爆菊,出来忽悠大家了。 --------------------编程问答-------------------- 菜鸟就是这样,只想使用语言提供的"优雅"的特性,殊不知这些"优雅"的背后的实现原理.

不能用for非要用foreach就是这样.

曾经在百度知道上回答别人的一个简单的数学算法,我给出了具体实现,然后下面就来了一菜鸟开始嘲讽,说用Math类
就可以了,那菜鸟不知道的是Math内部也是用类似的算法来实现的.在菜鸟的眼里,程序的效率跟代码行数的多少是挂钩的. --------------------编程问答--------------------
引用 81 楼 syx151 的回复:
菜鸟就是这样,只想使用语言提供的"优雅"的特性,殊不知这些"优雅"的背后的实现原理.

不能用for非要用foreach就是这样.

曾经在百度知道上回答别人的一个简单的数学算法,我给出了具体实现,然后下面就来了一菜鸟开始嘲讽,说用Math类
就可以了,那菜鸟不知道的是Math内部也是用类似的算法来实现的.在菜鸟的眼里,程序的效率跟代码行数的多少是挂钩的.

完全理解
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,