有关内置模板

本文介绍了迭代器的概念及其在C++中的应用,强调了迭代器作为访问非数组数据结构的工具。在Java中,各种数据结构继承于List,Vector作为其中的一员,提供了丰富的API进行元素操作。通过示例代码展示了如何使用Vector进行元素的添加、删除和遍历。此外,文章还探讨了Java中的Map接口,强调了其在一对一映射数据时的作用,并通过一个实际问题解释了如何利用Map解决重复单词的检测问题。
摘要由CSDN通过智能技术生成

迭代器(Iterator)

迭代器是 C++ 的知识,并不适用于 Java 和 Python 这两种语言。迭代器的知识点很复杂,实现方式看容器讲解。

对于数组我们可以采用指针进行访问,但是对于其他的存储空间连续的数据结构或者说是存储单元我们就需要找到另一种方式来替代指针的行为作用,从而达到对于非数组的数据结构的访问和遍历,于是我们定义了一种新的变量叫做迭代器。

定义:

迭代器是一种检查容器内元素并遍历元素的数据类型。

迭代器提供对一个容器中的对象的访问方法,并且定义了容器中对象的范围。

迭代器和指针的区别:

容器和 string 有迭代器类型同时拥有返回迭代器的成员。

如:容器有成员 .begin() 和 .end(),其中 .begin() 成员复制返回指向第一个元素的迭代器,即指向第一个元素的“地址”,而 .end() 成员返回指向容器尾元素的下一个位置的迭代器。

即 .begin() 指向的是第一个合法元素的位置,.end() 指向是容器后第一个不合法元素的地址。

相应的还有容器反向迭代器成员 .rbegin() .rend(), .rbegin() 返回容器的元素前最后一个不合法的地址,rend() 返回容器的最后一个合法地址。

容器迭代器的使用

每种容器类型都定义了自己的迭代器类型.

数据类型是由 vector< int> 定义的 iterator 类型。简单说就是容器类定义了自己的 iterator 类型,用于访问容器内的元素。每个容器定义了一种名为 iterator 的类型,这种类型支持迭代器的各种行为。

容器

在 Java 中各种数据结构都是继承于 list,所以 Java 的 list 功能很强,它的功能有很多。

Vector 容器(类)

线性表中有 Vector 和 list,两者作用比较相似。

Vector 的主要作用就是可变长度的数组,就把他当成数组使用即可。

 java 的实现方式:

//第一种构造方法创建一个默认的向量,默认大小为 10:
Vector()
//第二种构造方法创建指定大小的向量。
Vector(int size)
//第三种构造方法创建指定大小的向量,并且增量用 incr 指定。增量表示向量每次增加的元素数目。
Vector(int size,int incr)
//第四种构造方法创建一个包含集合 c 元素的向量:
Vector(Collection c)

以下为 Java Vector 的 API。

修饰符和类型方法和说明
booleanadd(E e)将指定的元素附加到此 Vector 的末尾。
voidadd(int index, E element)在此 Vector 的指定位置插入指定元素。
booleanaddAll(Collection<? extends E> c)将指定集合中的所有元素追加到末尾 这个向量,按照它们由指定的返回的顺序 集合的迭代器。
booleanaddAll(int index, Collection<? extends E> c)将指定 Collection 中的所有元素插入到此 指定位置的向量。
voidaddElement(E obj)将指定的组件添加到此向量的末尾, 将其大小增加一。
intcapacity()返回此向量的当前容量。
voidclear()从此 Vector 中删除所有元素。
Objectclone()返回此向量的克隆。
booleancontains(Object o)退货 true 如果此向量包含指定的元素。
booleancontainsAll(Collection<?> c)如果此 Vector 包含所有元素,则返回 true 指定的集合。
voidcopyInto(Object[] anArray)将此向量的分量复制到指定的数组中。
EelementAt(int index)返回指定索引处的组件。
Enumerationelements()返回此向量的组件的枚举。
voidensureCapacity(int minCapacity)如有必要,增加此向量的容量,以确保它至少可以容纳由指定的组件数量最小容量参数。
booleanequals(Object o)比较指定的 Object 与此 Vector 是否相等。
EfirstElement()返回第一个组件(索引处的项目 0) 的这个向量。
Eget(int index)返回此 Vector 中指定位置的元素。
inthashCode()返回此 Vector 的哈希码值。
intindexOf(Object o)返回指定元素第一次出现的索引 在此向量中,如果此向量不包含该元素,则为 -1。
intindexOf(Object o,int index)返回指定元素第一次出现的索引这个向量,从 index, 或返回 -1 如果 未找到该元素。
voidinsertElementAt(E obj, int index)将指定对象作为组件插入此向量中的 指定的 index.
booleanisEmpty()测试此向量是否没有组件。
Iteratoriterator()以适当的顺序返回此列表中元素的迭代器
ElastElement()返回向量的最后一个组件。
intlastIndexOf(Object o)返回指定元素最后一次出现的索引在此向量中,如果此向量不包含该元素,则为 -1。
intlastIndexOf(Object o, int index)返回指定元素最后一次出现的索引这个向量,从 index, 或返回 -1 如果 未找到该元素。
ListIteratorlistIterator()返回此列表中元素的列表迭代器(在适当的顺序)。
ListIteratorlistIterator(int index)返回此列表中元素的列表迭代器(在适当的序列),从列表中的指定位置开始。
Eremove(int index)移除此 Vector 中指定位置的元素。
booleanremove(Object o)移除此 Vector 中第一次出现的指定元素如果 Vector 不包含该元素,则它保持不变。
booleanremoveAll(Collection<?> c)从此 Vector 中删除其包含在指定的集合。
voidremoveAllElements()从此向量中删除所有组件并将其大小设置为零。
booleanremoveElement(Object obj)删除参数的第一个(最低索引)出现从这个向量。
voidremoveElementAt(int index)删除指定索引处的组件。
protected voidremoveRange(int fromIndex, int toIndex)从此列表中删除索引介于两者之间的所有元素 fromIndex,包括在内,和 toIndex, 独家的。
booleanretainAll(Collection<?> c)仅保留此 Vector 中包含在指定的集合。
Eset(int index, E element)将此 Vector 中指定位置的元素替换为指定的元素。
voidsetElementAt(E obj,int index)将组件设置在指定的位置 index 这个的向量是指定的对象。
voidsetSize(int newSize)设置此向量的大小。
intsize()返回此向量中的组件数。
ListsubList(int fromIndex,int toIndex)返回此列表中 fromIndex 之间的部分的视图
Object[]toArray()返回一个包含此 Vector 中所有元素的数组以正确的顺序。
 T[]toArray(T[] a)返回一个包含此 Vector 中所有元素的数组正确的顺序; 返回数组的运行时类型指定数组。
StringtoString()返回此 Vector 的字符串表示形式,包含 每个元素的字符串表示。
voidtrimToSize()将此向量的容量修剪为向量的电流 尺寸。

遍历 Vector

Enumeration vEnum = v.elements();
while (vEnum.hasMoreElements())
    System.out.print(vEnum.nextElement() + " ");

快递的分拣

快递员需要对快递进行分拣,现在小李是一名快递员,他想要你帮他设计一个程序用于快递的分拣,按城市分开。

现在有以下输入:

单号 省份

请你将单号按照城市分开,并输出。

城市按照输入顺序排序

单号按照输入顺序排序

样例如下:

输入
10 
10124214 北京
12421565  上海
sdafasdg213 天津
fasdfga124 北京
145252  上海
235wtdfsg 济南
3242356fgdfsg 成都
23423 武汉  
23423565f 沈阳
1245dfwfs 成都

输出
北京 2
10124214
fasdfga124
上海 2
12421565
145252
天津 1
sdafasdg213
济南 1
235wtdfsg
成都 2
3242356fgdfsg 
1245dfwfs 
武汉 1
23423
沈阳 1
23423565f 

首先我们要知道中国城市肯定在 1000 个以内,但是单号我们不确定,我们不可能每个数组开 10000 个,那样内存不够,所以这时候我们就用到了我们的 vector,他的容量是动态申请的,在比赛中我们可以理解为无限制。

  • 第一步:我们创建一个 vector 用于保存地址
static Vector city=new Vector<String>();

  • 第二步:我们创建一个 vector 组用于存放单号
static Vector <Vector<String>> dig= new Vector <Vector<String>>();

注意: city是一个表,dig是一堆表。city里每一个下标都代表不同的城市,且每个下标都能再dig中找到对应的表,而dig中所对应的表用来存放对应的单号。

  • 第三步:我们定义一个映射函数,因为你的城市可能会再次出现,你需要知道之前有没有。

当我们输入城市字符串时需要了解city表里有没有,没有就用addElement(E obj)将城市字符串添加到city的末尾, 将其大小增加一,如果有就返回下标,利用返回的下标在dig中找到对应的表把单号存放进去。

  • 第四步:我们开始读入操作并按照顺序进行存放

dig中存放存放单号时要注意dig的下标是[city.size()-1]。因为city开始存元素时size为1,下标为0.即city[i]的i是从0开始,而city.size()是从1开始。同样的dig[i]的i也是从0 开始,所以需要city.size()-1。

完整代码

import java.util.List;
import java.util.Scanner;
import java.util.Vector;

public class Main {

  static Vector city=new Vector<String>();

  static Vector <Vector<String>> dig= new Vector <Vector<String>>();

  static int Myfind(String s)
  {//判断这个城市有没有出现过,如果有就返回它的下标

      for(int i=0;i<city.size();i++)
      {
          if(city.get(i).equals(s)) {
              return i;
          }
      }

      return -1;
  }

  public static void main(String[] args) {


      int n;
      Scanner in=new Scanner(System.in);
      n=in.nextInt();
      for(int i=0;i<n;i++)
      {
          String d,c;
          d=in.next();
          c=in.next();
          int flag=Myfind(c);
          if(flag==-1){//如果不存在那就再city里创建一个
              city.addElement(c);//addElement(E obj)将指定的组件添加到此向量的末尾, 将其大小增加一。
              dig.addElement(new Vector<String>());
              dig.get(city.size()-1).addElement(d);//当city开始存东西时.size()是1,但是city的下标是0.

          }
          else   dig.get(flag).addElement(d);//存在便返回它的下标再dig里找到,并把单号放进去
      }
      for(int i=0;i<city.size();i++)
      {
          System.out.println(city.get(i)+" "+dig.get(i).size());

          for(int j = 0; j< dig.get(i).size(); j++)
              System.out.println(dig.get(i).get(j));
      }
  }


}

队列 Queue

Java 中的队列

定义方式:

Queue<String> queue = new LinkedList<String>();

部分成员函数(包括继承的):

  • add(): 增加一个元索,如果队列已满,则抛出一个异常
  • remove():移除并返回队列头部的元素,如果队列为空,则抛出一个异常
  • element():返回队列头部的元素,如果队列为空,则抛出一个异常
  • offer():添加一个元素并返回 true,如果队列已满,则返回 false
  • poll(): 移除并返问队列头部的元素,如果队列为空,则返回 null
  • peek(): 返回队列头部的元素,如果队列为空,则返回 null
  • put(): 添加一个元素, 如果队列满,则阻塞
  • take(): 移除并返回队列头部的元素,如果队列为空,则阻塞
  • size(): 返回队列长度。

CLZ 的银行。

第一行 M 次操作(M<1000)

第二行 到 第M+1行 输入操作

格式:   IN name V
        OUT V
        IN name2 N
        OUT N
        即 第一个字符串为操作 是IN进入排队和OUT 出队
            IN 排队 跟着两个字符串为姓名和权限V或N
            OUT 为出队即完成操作,V和N代表那个窗口完成了操作

输出:M次操作后V队列和N队列中姓名,先输出V队列后输出N队列。

样例:

输入:

5
IN xiaoming N
IN Adel V
IN laozhao N
OUT N
IN CLZ V

输出:

Adel
CLZ
laozhao

借此题了解一下预置代码的方便性。

完整代码


import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    static Queue<String> V=new LinkedList<String>();

    static Queue<String> N=new LinkedList<String>();

    public static void main(String[] args) {

        int M;
        Scanner in=new Scanner(System.in);
        M=in.nextInt();
        while(M>0) //
        {
            M--;
            String op,name,type;
            op=in.next();
            // System.out.println("op"+op);
            if(op.contains("IN"))
            {
                name=in.next();
                type=in.next();
                if(type.contains("V")) {
                    V.offer(name);//offer():添加一个元素并返回 true,如果队列已满,则返回 false
                }
                else {
                    N.offer(name);
                }
                // System.out.println("name:"+name+"type:"+type);

                // System.out.println(Vqueue);
            }
            else
            {
                type=in.next();
                if(type.contains("V")){
                    V.poll();
                }
                else {
                    N.poll();
                }
                // System.out.println("type"+type);
            }
        }

        while(V.size()!=0)
        {
            System.out.println(V.poll());
        }
        while(N.size()!=0)
        {
            System.out.println(N.poll());
        }
    }

}

Map 映射

map 是一个关联容器,它提供一对一的 hash。

  • 第一个可以称为关键字(key),每个关键字只能在 map 中出现一次
  • 第二个可称为该关键字的值(value)

map 以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map 主要用于资料一对一映射的情況,在 map 内部所有的数据都是有序的。

比如,像是管理班级内的学生,Key 值为学号,Value 放其他信息的结构体或者类。

Java 中的 map

定义方法:

Map m1 = new TreeMap(); 

java里的有序map是Treemap,不排序的map是Hashmap,如果不需要排序可以直接使用。

成员方法

方法名方法描述
void clear( )从此映射中移除所有映射关系(可选操作)。
boolean containsKey(Object k)如果此映射包含指定键的映射关系,则返回 true。
boolean containsValue(Object v)如果此映射将一个或多个键映射到指定值,则返回 true。
boolean equals(Object obj)比较指定的对象与此映射是否相等。
Object get(Object k)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
int hashCode( )返回此映射的哈希码值。
boolean isEmpty( )如果此映射未包含键-值映射关系,则返回 true。
Set keySet( )返回此映射中包含的键的 Set 视图。
Object put(Object k, Object v)将指定的值与此映射中的指定键关联
Object remove(Object k)如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
int size( )返回此映射中的键-值映射关系数。
Collection values( )返回此映射中包含的值的 Collection 视图。

弗里石的的语言

小发明家弗里想创造一种新的语言,众所周知,发明一门语言是非常困难的,首先你就要克服一个困难就是,有大量的单词需要处理,现在弗里求助你帮他写一款程序,判断是否出现重复的两个单词。

有重复就输出重复单词,重复就输出 NO,多个重复输出最先出现的哪一个。

输入:


第 1 行,输入N,代表共计创造了多少个单词
第 2 行至第 N+1 行,输入 N 个单词

格式:  

    fjsdfgdfsg
    fdfsgsdfg
    bcvxbxfyres 
 

现在有以下样例输入:

样例 1

输入:

6
1fagas 
dsafa32j
lkiuopybncv
hfgdjytr
cncxfg
sdhrest

输出:

NO

样例 2


输入:

5
sdfggfds
fgsdhsdf
dsfhsdhr
sdfhdfh
sdfggfds

输出:

sdfggfds

这里使用映射和字典解题

代码如下:


import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

public class Main {

  static Map mp=new TreeMap();

  public static void main(String[] args)
  {

      int n;
      boolean flag=false;
      Scanner in=new Scanner(System.in);
      String ans="NO";
      n=in.nextInt();
      for(int i=0;i<n;i++)
      {
          String word;
          word=in.next();
          // System.out.println(Hx(word));
          if(flag) continue;

          if(mp.containsKey(word)){//boolean containsKey(Object k)	如果此映射包含指定键的映射关系,则返回 true。
              flag=true;
              ans=word;
          }
          else {
              mp.put(word,true);//Object put(Object k, Object v) 将指定的值与此映射中的指定键关联

          }
      }
      System.out.println(ans);
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值