精华内容
下载资源
问答
  • 可进行逆层次遍历树,例如1(2(4,5),3(6,7))输出4
  • 一、概述List遍历是我们经常会使用到的一个功能,很多时候我们也会用到反向遍历,在用到反向遍历时我们常用的方法是通过for循环或者是对List反向排序来完成相应的操作,像下面代码这样:方法1:for(int i = list.size...

    一、概述

    List遍历是我们经常会使用到的一个功能,很多时候我们也会用到反向遍历,在用到反向遍历时我们常用的方法是通过for循环或者是对List反向排序来完成相应的操作,像下面代码这样:

    方法1:

    for(int i = list.size()-1; i>=0; i--) {

    System.out.println(list.get(i));

    }

    这个方法开上去就比较臃肿,写起来也相对繁琐一些。

    方法2:

    Collections.reverse(list);

    System.out.println(list);

    这种方法看似不错,但是reverse改变了原list的结构,如果我们只是要反向遍历list而不想改变list的结构的话这个方法是不适用的,除非你想在遍历完list之后再次调用reverse把list变回去,这种做法当然是不值得推荐的。

    那么有没有一种方法可以既不改变原有的List的结构,有可以很简洁的实现反向遍历呢?我个人认为,直接制作一个支持反向遍历的List就可以很好的解决这个问题。下面我们就从头开始制作支持反向遍历List。

    二、准备工作

    众所周知,所有的Collection都实现了Iterable接口,而Iterable接口中的iterator()方法就是用来实现集合类遍历的,那么我们是不是可以从这里开始入手。

    还有一点,就是为什么要基于ArrayList去做这件事而不是直接实现List接口,原因很简单,如果我要实现List接口那么我就需要实现List接口中所有的方法,而我比较懒,不想再去实现List接口中的所有方法,而且一般需要遍历处理的都是ArrayList,所有我就直接在ArrayList的基础上去做这件事,也省了不少功夫。

    三、新建List

    话不多说,开干。首先我们需要定义一个类,并且这个类要继承ArrayList:

    public class ErgodicList extends ArrayList {

    /*构造方法 start*/

    public ErgodicList() {

    super();

    }

    public ErgodicList(Collection extends T> integers) {

    super(integers);

    }

    /*构造方法 end*/

    }

    接着我们要编写能够实现反向遍历的Interator:

    /**

    * 反向遍历Iterator

    *

    * @return Iterable

    */

    public Iterable reversed() {

    return () -> new Iterator() {

    int index = ErgodicList.super.size() - 1;

    @Override

    public boolean hasNext() {

    return index > -1;

    }

    @Override

    public T next() {

    return ErgodicList.super.get(index--);

    }

    // Java8以下版本需要重写该方法

    // @Override

    // public void remove() {

    // throw new UnsupportedOperationException("remove");

    // }

    };

    }

    从代码可以看出,首先我们要取出List最末尾的Index,这一点跟for循环很像,然后就是重写Iterator接口的两个方法(java8种remove()有了默认方法,我这里也不需要它所以就没有重写),一个用来判断是否还有下一个元素,一个用来获取元素。

    到此可以支持反向遍历的List就编写好了,是不是感觉比for循环还要复杂,但是这属于一劳永逸的方法,麻烦一次以后再也不用苦逼的写for循环了。下面我们来测试一下效果如何:

    public static void main(String[] args) {

    ErgodicList integers = new ErgodicList<>(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9));

    System.out.println("------------反向遍历结果-------------");

    integers.reversed().forEach(System.out::println);

    System.out.println("------------------------------------");

    System.out.println(integers);

    }

    241c928f296b70a49fd5f8a37f4a2e34.png

    从结果可以看出,简单的foreach代码在不改变原有List的结构的情况下(废话Interator当然不会改变List的结构)实现了List的反向遍历,并且以后再需要反向遍历的时候我们只需要new一个我们自制的List再加一个forEach就好了,用起来相当方便。

    四、衍生

    我们既然实现了反向遍历,那么可不可以实现随机遍历呢,当然没问题,举一反三是我们程序员应有的基本素养。下面来看看随机遍历的实现,还是刚才的那个List,我们再增加一个方法:

    /**

    * 随机遍历Iterator

    *

    * @return Iterable

    */

    public Iterable random() {

    return () -> {

    List randomList = new ArrayList<>(this);

    Collections.shuffle(randomList, new Random());

    return randomList.iterator();

    };

    是不是更简单,具体的说明我就不写了(我比较懒),有兴趣的朋友可以自己查一下。测试代码和反向遍历的测试也差不多,只需要:

    integers.random().forEach(System.out::println);

    使用起来体验也是很不错的,大家可以试一试。

    ------------------------------------------------------------------------------

    欢迎关注我的个人公众号,推送最新文章

    展开全文
  • 正向遍历和反向遍历

    千次阅读 2021-03-14 20:39:49
    反向遍历删除(多线程) public static void main(String[] args) { ArrayList list = new ArrayList(); list.add("111"); list.add("222"); list.add("222"); list.add("333"); list.add("444"); list.add("333");...

    前言

    之前搜索面试题的时候,出现了一个题:一个ArrayList在循环过程中删除,会不会出问题,为什么?心里想的答案是肯定会有问题但是又不知道是为什么,在搜索到答案后,发现里面其实并不简单,所以专门写篇文章研究一下。

    for循环正向删除

    先看示例,再解析原因:

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    //for循环正向循环删除

    for (int i = 0;i < list.size();i++){

    if (list.get(i).equals("222")){

    list.remove(i);

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    运行后,输出结果:

    [111, 222, 333, 444, 333]

    发现,相邻的字符串“222”没有删除,这是为什么呢?画图解释:

    dc6654ab2ced593259393968ec15e2fe.png

    解释:删除元素“222”,当循环到下标为1的元素的的时候,发现此位置上的元素是“222”,此处元素应该删除,根据上图中的元素移动可知,在删除元素后面的所有元素都要向前移动一个位置,那么移动之后,原来下标为2的元素“222”,此时下标为1,这是在i = 1,时的循环操作,在下一次的循环中,i = 2,此时就遗漏了第二个元素“222”。

    那么再做下一个测试,删除元素“333”,结果将如何?

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    //for循环正向循环删除

    for (int i = 0;i < list.size();i++){

    if (list.get(i).equals("333")){

    list.remove(i);

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    运行结果:

    [111, 222, 222, 444]

    发现,没有问题。原理在上一个测试已经说了,就不再赘述。

    总结:for循环正向删除,会遗漏连续重复的元素。

    for循环反向删除

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    //for循环反向循环删除

    for (int i = list.size() - 1;i >= 0;i--){

    if (list.get(i).equals("222")){

    list.remove(i);

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    运行结果:

    [111, 333, 444, 333]

    发现,没有问题。还是画图解释:

    607c0187d3d30593afc6fd8fba36c1b7.png

    反向删除的时候,循环遍历完了的元素下标才有可能移动(已经遍历的元素,下标变化了也没有影响),所以没有遍历的下标不会移动,自反向删除会遍历到所有的元素,正向会跳过一些元素。

    总结:反向遍历删除,没有问题(单线程)。

    反向遍历删除(多线程)

    public static void main(String[] args) {

    ArrayList list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    Thread thread1 = new Thread() {

    @Override

    public void run() {

    remove(list,"111");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    Thread thread2 = new Thread() {

    @Override

    public void run() {

    remove(list, "222");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    Thread thread3 = new Thread() {

    @Override

    public void run() {

    remove(list, "333");

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    };

    // 使各个线程处于就绪状态

    thread1.start();

    thread2.start();

    thread3.start();

    // 等待前面几个线程完成

    try {

    thread1.join();

    thread2.join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    public static void remove(ArrayList list, String elem) {

    // 普通for循环倒序删除,删除过程中元素向左移动,不影响连续删除

    for (int i = list.size() - 1; i >= 0; i--) {

    if (list.get(i).equals(elem)) {

    list.remove(list.get(i));

    }

    }

    }

    运行结果:

    [444]

    总结:多线程反向遍历删除,没有问题。

    Iterator循环删除

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    //foreach循环删除

    Iterator iterator = list.iterator();

    while (iterator.hasNext()){

    if (iterator.next().equals("222")){

    list.remove(iterator.next());

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    运行结果:

    Exception in thread "main" java.util.ConcurrentModificationException

    at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)

    at java.util.ArrayList$Itr.next(ArrayList.java:859)

    at joe.effective.Test.main(Test.java:20)

    这个问题就要借助源码来分析了(JDK1.8):

    public E remove(int index) {

    rangeCheck(index);

    modCount++;

    E oldValue = elementData(index);

    int numMoved = size - index - 1;

    if (numMoved > 0)

    System.arraycopy(elementData, index+1, elementData, index,

    numMoved);

    elementData[--size] = null; // clear to let GC do its work

    return oldValue;

    }

    public boolean remove(Object o) {

    if (o == null) {

    for (int index = 0; index < size; index++)

    if (elementData[index] == null) {

    fastRemove(index);

    return true;

    }

    } else {

    for (int index = 0; index < size; index++)

    if (o.equals(elementData[index])) {

    fastRemove(index);

    return true;

    }

    }

    return false;

    }

    private void fastRemove(int index) {

    modCount++;

    int numMoved = size - index - 1;

    if (numMoved > 0)

    System.arraycopy(elementData, index+1, elementData, index,

    numMoved);

    elementData[--size] = null; // clear to let GC do its work

    }

    可以看出,ArrayList的remove方法,一种是根据下标删除,一种是根据元素删除。

    发现即使看了remove方法的源码也不能找到报错的原因,由于我们使用了Iterator迭代器,那么再看看迭代器的源码,果不其然,就发现了问题所在:

    private class Itr implements Iterator

    private class ListItr extends Itr implements ListIteratorpublic void remove() {

    if (lastRet < 0)

    throw new IllegalStateException();

    checkForComodification(); // 检查修改次数

    try {

    ArrayList.this.remove(lastRet);

    cursor = lastRet;

    lastRet = -1;

    expectedModCount = modCount;

    } catch (IndexOutOfBoundsException ex) {

    throw new ConcurrentModificationException();

    }

    }

    final void checkForComodification() {

    if (modCount != expectedModCount)

    throw new ConcurrentModificationException();

    }

    Itr和ListItr是ArrayList的两个私有内部类,Itr实现了Iterator接口,ListItr继承了Itr类和实现了ListIterator接口。Itr类中也有一个remove方法,迭代器实际调用的也正是这个remove方法,上述源码也就是这个方法的源码。

    由源码的第二段代码可以看出,这个remove方法中调用了ArrayList中的remove方法,在这个方法中我们注意到了expectedModCount变量和modCount变量,modCount在前面的代码中也见到了,它记录了ArrayList修改的次数,而前面的变量expectedModCount,这个变量的初值和modCount是相等的;同时在ArrayList.this.remove(lastRet);代码面前,调用了检查次数的方法checkForComodification(),这个方法做的事情很简单,就是如果expectedModCount和modCount不相等,那么就抛出异常ConcurrentModificationException。

    我们在用Iterator循环删除的时候,调用的是ArrayList里面的remove方法,删除元素后modCount会增加,expectedModCount则不变,这样就造成了expectedModCount != modCount,那么就抛出异常了。

    再用Iterator中的remove方法来测试:

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    Iterator iterator = list.iterator();

    while (iterator.hasNext()){

    if (iterator.next().equals("222")){

    iterator.remove();

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }

    运行结果[111, 333, 444, 333]

    发现,删除成功且没有报错。

    什么原因呢?我们调用的了Iterator中的迭代器删除元素,在这个方法中有:expectedModCount = modCount这样一句代码,所以当我们每删除一次元素,就同步一次,所以调用checkForComodification()时,就不会报错。如果换到多线程中,这个方法不能保证两个变量修改的一致性,结果具有不确定性,所以不推荐这种方法。

    总结:Iterator调用ArrayList的删除方法报错,Iterator调用迭代器自己的删除方法,单线程不会报错,多线程会报错。

    forEach循环删除

    public static void main(String[] args){

    List list = new ArrayList();

    list.add("111");

    list.add("222");

    list.add("222");

    list.add("333");

    list.add("444");

    list.add("333");

    //foreach循环删除

    for (String str : list){

    if (str.equals("222")){

    list.remove(str);

    }

    }

    System.out.println(Arrays.toString(list.toArray()));

    }运行结果

    Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)

    at java.util.ArrayList$Itr.next(ArrayList.java:859)

    at joe.effective.Test.main(Test.java:20)

    报错。

    foreach原理是因为这些集合类都实现了Iterable接口,该接口中定义了Iterator迭代器的产生方法,并且foreach就是通过Iterable接口在序列中进行移动。也就是说:在编译的时候编译器会自动将对for这个关键字的使用转化为对目标的迭代器的使用

    明白了原理就跟上述的Iterator删除调用ArrayList中remove一样了。

    总结:forEach循环删除报错。

    展开全文
  • 积压订单中的订单总数》 时用到了map的反向遍历,看到问题时首先想到了优先队列,但是需要维护一个大根堆和一个小根堆,感觉操作起来比较麻烦,突发奇想使用map就能够解决。map本身就是有序的,正向遍历可以得到...

    前言

    今天在解决一个问题 《5710. 积压订单中的订单总数》 时用到了map的反向遍历,看到问题时首先想到了优先队列,但是需要维护一个大根堆和一个小根堆,感觉操作起来比较麻烦,突发奇想使用map就能够解决。map本身就是有序的,正向遍历可以得到从小到大的序列,而反向遍历就可以得到从大到小的序列,这个思路本身没有错,但是解题时卡在了反向遍历时如何删除元素的知识点上,特此记录一下。

    map的正向遍历

    map的正向遍历是一个基础知识点了,先简单复习一下,不管是用 for 还是 while,只要控制迭代器持续前进就可以了。

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (map<int, string>::iterator it = mp.begin(); it != mp.end(); ++it) {
        cout << it->first << " " << it->second << endl;
    }
    
    /* 输出内容
    1 A
    2 E
    3 I
    4 O
    6 U
    */
    

    引入 auto 关键字以后,定义表示式的时候会更加方便一点

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto it = mp.begin(); it != mp.end(); ++it) {
        cout << it->first << " " << it->second << endl;
    }
    

    引入冒号以后表达式更加简短,要注意的是这里的 it 已经不是指针了,而是 value_type 类型,所以需要是用 . 来访问

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto it : mp) {
        cout << it.first << " " << it.second << endl;
    }
    

    引入了结构化绑定声明之后,遍历方式还可以写成下面这样

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto& [a, b] : mp) {
        cout << a << " " << b << endl;
    }
    

    map 遍历时删除元素

    map 遍历时删除需要注意迭代器失效问题,常用的有下面两种写法

    it = mp.erase(it);
    

    或者

    mp.erase(it++);
    

    遍历删除时的例子:

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto it = mp.begin(); it != mp.end();) {
        if (it->second == "I")
            mp.erase(it++);
        else
            it++;
    }
    
    for (auto it : mp) cout << it.first << " " << it.second << endl;
    
    /* 输出内容
    1 A
    2 E
    4 O
    6 U
    */
    

    map 的反向遍历

    map 反向遍历时可以使用 reverse_iterator 迭代器,配合 rbegin()rend() 方法就可以完成反向遍历

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto it = mp.rbegin(); it != mp.rend(); it++) {
        cout << it->first << " " << it->second << endl;
    }
    /* 输出内容
    6 U
    4 O
    3 I
    2 E
    1 A
    */
    

    map 反向遍历时删除元素

    一开始也是用 erase 函数来删除元素,但是会报下面的编译错误

    error: no matching function for call to ‘std::map<int, std::__cxx11::basic_string<char> >::erase(
        std::reverse_iterator<std::_Rb_tree_iterator<std::pair<const int, std::__cxx11::basic_string<char> > > >)’
        mp.erase(it++);
    

    查询文档发现,erase 函数重载只有下面几种实现:

    void erase( iterator pos );                                     (until C++11)
    iterator erase( const_iterator pos );                           (since C++11)
    iterator erase( iterator pos );                                 (since C++17)
    
    void erase( iterator first, iterator last );                    (until C++11)
    iterator erase( const_iterator first, const_iterator last );    (since C++11)
    
    size_type erase( const key_type& key );
    

    参数是迭代器的函数并不支持 reverse_iterator,需要将 reverse_iterator 转化成 iterator 才可以,这时就需要用到 base 函数,对 reverse_iterator 类型的迭代器使用 base 函数得到的是上一个元素“原始指针”,这一点比较有意思,具体的解释可以参考 《std::reverse_iterator::base》,这种操作决定了我们遍历删除的写法,应该是先自增再调用 base 函数,代码如下;

    map<int, string> mp{{1, "A"}, {2, "E"}, {3, "I"}, {4, "O"}, {6, "U"}};
    
    for (auto it = mp.rbegin(); it != mp.rend();) {
        if (it->second == "I") mp.erase((++it).base());
        else it++;
    }
    
    for (auto it = mp.rbegin(); it != mp.rend(); it++)
        cout << it->first << " " << it->second << endl;
    
    /* 输出内容
    6 U
    4 O
    2 E
    1 A
    */
    

    总结

    • map 默认会按照 key 排序,是一个常用的有序容器
    • 配合使用 rbegin()rend() 函数可以完成 map 的反向遍历
    • reverse_iterator 类型迭代器使用 base() 函数,可以转化成 iterator 相关类型,然后进行删除操作

    ==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==

    搬起砖,我抱不了你,放下砖 … 我尽力!

    展开全文
  • } } //反向遍历链表 void R_Print(LNode *L) { if (L->next != NULL) { R_Print(L->next); //递归 } if (1) { printf("%d ", L->data); } } int main() { LNode *L = List_TailInsert(); PrintList(L); ...
    #include<stdio.h>
    #include<stdlib.h>
    typedef int ElemType;
    
    typedef struct LNode {
    	ElemType data; //数据域
    	struct LNode *next; //指针域
    
    } LNode;
    
    //尾插法建立单链表
    LNode* List_TailInsert() {
    	int x;
    	LNode *L = (LNode*) malloc(sizeof(LNode)); //创建头结点,L为头指针
    	LNode *s;
    	LNode *r = L; //r为表尾指针,r一直指向表为结点
    	scanf("%d", &x); //输入节点的值
    	while (x != 999) { //输入999表示结束
    
    		s = (LNode*) malloc(sizeof(LNode));
    		s->data = x;
    		r->next = s;
    		r = s; //r指向新的表尾节点
    		scanf("%d", &x);
    	}
    	r->next = NULL; //尾结点的指针置为空
    	return L;
    }
    
    //遍历链表
    void PrintList(LNode *L) {
    	LNode *p;
    	p = L->next;
    	printf("遍历单链表: ");
    	while (p->next != NULL) {
    
    		printf("%d ", p->data);
    		p = p->next;
    	}
    	if (p->next == NULL) { //输出最后一个元素
    		printf("%d ", p->data);
    		printf("\n");
    	}
    
    }
    
    //反向遍历链表
    void R_Print(LNode *L) {
    
    	if (L->next != NULL) {
    		R_Print(L->next); //递归
    	}
    	if (1) {
    		printf("%d ", L->data);
    	}
    }
    
    int main() {
    	LNode *L = List_TailInsert();
    	PrintList(L);
    	LNode *P = L->next;
    	printf("反向遍历单链表: ");
    	R_Print(P);
    
    }
    
    
    展开全文
  • 反向遍历数组

    千次阅读 2019-07-25 15:26:18
    /*Recerse a number */ #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #define N 10 int main() { int a[N], i; printf("Enter %d number: ", N); for (i = 0;... scanf("%d", ...
  • 一般的正向集合遍历 1. for/index/size模式 for(int i = 0; i < collection.size(); ++i) { std::cout << collection[i] << std::endl; } 弊端: 只适合std::vector这种可以通过下标随机O(1)时间...
  • C++中迭代器反向遍历

    千次阅读 2020-03-24 19:28:13
    map<int, string>::reverse_iterator iter; for (iter = mouse.rbegin(); iter!=mouse.rend(); iter++) { cout<<iter->second << endl; }
  • std::map 反向遍历

    千次阅读 2020-01-10 16:08:22
    1、反向遍历:可以使用反向迭代器reverse_iterator反向遍历map映照容器中的数据,它需要rbegin()和rend()方法指出反向遍历的起始位置和终止位置。 #pragma warning(disable:4786) #include<iostream> #include...
  • 我们通常情况下都是正向遍历一个列表,下面是一种简单的反向遍历一个列表的方式。 ## 正向遍历 >>>A = [9, 8, 7] >>>for index, a in enumerate(A): print(str(index) +' '+ str(a)) 0 9 1 8 2 ...
  • List逆向遍历、反向遍历--Iterator详解

    万次阅读 2017-12-26 20:26:58
    List逆向遍历、反向遍历–Iterator详解概述在使用java集合的时候,都需要使用Iterator。但是java集合中还有一个迭代器ListIterator,在使用List、ArrayList、LinkedList和Vector的时候可以使用。这两种迭代器有什么...
  • 1 std::map正向遍历 1.1 for循环 #include <iostream> #include <string> #include <map> int main() { std::map<int, std::string> t_Map; t_Map[0] = "A"; t_Map[1] = "B"; t_Map[2]...
  • QMap的反向遍历

    千次阅读 2019-12-31 16:13:30
    //测试函数 void Widget::MainTest() { QMap<QString,QString> MapTestR; for(int i = 0;i < 10;i++) { MapTestR.insert(QString::number(i),QString::number(i+1)); ...::Iter...
  • ListIterator 反向遍历遇到的问题

    千次阅读 2021-12-04 09:56:50
    public static void main(String[] args) { List ... } } 反向遍历时发现lt.hasPrevious()为false,查阅资料发现,列表迭代器遍历时默认指针在最左侧,所以要想使用列表迭代器反向遍历首先要正向遍历把指针指到最右侧。
  • map 反向遍历

    千次阅读 2018-08-31 11:39:33
    1、反向遍历:可以使用反向迭代器reverse_iterator反向遍历map映照容器中的数据,它需要rbegin()和rend()方法指出反向遍历的起始位置和终止位置。 #pragma warning(disable:4786) #include&lt;iostream&gt;...
  • 先把中文数字和单位做个映射,然后正向遍历,用数字乘以单位,然后直接把他们累加起来就搞定了。 一百二十三的解析式为1*100 + 2*10 + 3,代码如下: # 数字映射 number_map = { "零": 0, "一": 1, "二": 2, ...
  • vector array; array.push_back( 1 ); array.push_back( 2 ); array.push_back( 3 );...for( vector::size_type i=array.size()-1;... --i ) // 反向遍历array数组 { cout << array[i] << endl...
  • 二叉树反向遍历

    千次阅读 2017-10-15 22:48:56
    //编写一道自下而上,从右至左的二叉树层次遍历 #include typedef struct BiTree() { int data; struct BiTree *lchild,*rchild; }BiTNode,*BiTree; void RelevelOrder(BiTree T) { InitStack(S); InitQueue...
  • JS 逆向循环,JS 反向遍历

    千次阅读 2020-06-02 17:48:10
    datalist.reverse();//翻转的核心函数reverse() for (var i = 0; i < datalist.length; i++) { var record = "<div class='mesbox unread recordlist' name=" + datalist[i].credit_code + ">...
  • 如何反向遍历List集合

    2018-07-26 09:51:00
    迭代器遍历hasPrevious()方法用于反向遍历的时候判断是否还有下一个元素 while (li.hasPrevious()) { System.out.print(li.previous() + " " ); } } }   转载于:...
  • LinkedHashMap 反向遍历

    千次阅读 2018-06-19 09:33:50
    import java.util.*; public class Test { public static void main(String[] args) { // Map&lt;String,Object&gt; hashMap = new HashMap&lt;&gt;(16); // for(int i=0;...// ...
  • 1. reversed() a = [1, 2, 3, 4] for i in reversed(a): print(i) 2. range(len(a)-1, -1, -1) ''' 遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,互帮互助,群里还有...
  • python range()函数反向遍历的几种表达

    千次阅读 2019-03-31 08:33:31
    for i in range(10,0,-2):#有10 print(i) print('1111111111111111111111111111') for i in range(0,10,2):#没10 print(i) print('2222222222222222222222222222') for i in range(10,0,2):#不输出不报错 ...
  • 1. reversed() a = [1, 2, 3, 4] for i in reversed(a): print(i) 2. range(len(a)-1, -1, -1) a = [1, 2, 3, 4] for i in range(len(a)-1, -1, -1): print(a[i]) 3. range(len(a)) + ~操作符 ...
  • 2、创建单链表以及遍历方法,正向遍历网上较多,所以以下提出了两种反向遍历方法   public class NodeTest { Nodehead = null; Nodepoint = null; NodenewNode = null; Nodenod = null; publicstatic int ...
  • 我首先想到的思路就是使用for循环遍历字符串,利用字符串操作符x in s(如果x是s的子串,返回True,否则返回False),使用if函数 ,若为True则删除(remove)该元素。最终输出新列表。思路代码及运行结果...
  • 反向遍历链表

    2020-02-23 11:59:18
    反向遍历链表,不改变链表结构。 利用栈的先进后出。 public static void reversePrint(HreoNode node){ if(node.next==null){ return; } //创建栈 Stack<HreoNode> stack = new Stack<HreoNode>...
  • 反向遍历list的思路及js及json的总结

    千次阅读 2017-11-03 21:57:58
    思路一:  for(int i =list.size()-1;i>=0;i--){  //输出处理  } 思路二:Collections.reverse(list),然后输入。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 84,537
精华内容 33,814
关键字:

反向遍历

友情链接: snakeGame.zip