题目描述
请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符"go"时,第一个只出现一次的字符是"g"。当从该字符流中读出前六个字符“google"时,第一个只出现一次的字符是"l"。
输出描述:
如果当前字符流没有存在出现一次的字符,返回#字符。
最开始看到这个题目的时候自己感觉没有思路,就直接跳过了,然后开始看其他的题目,但是在翻看自己博客的时候看到了一个可以解决这个问题的方法。就是哈希,因为学过哈希已经过去一段时间了,所以自己开始并没有想到这个方法。
并且自己的应变能力和思维能力确实比较差,题目稍微有变动就不知道怎么去解决。自己之前写的时候是一个函数,通过传进来的参数是一个字符串来求解,但是这道题目却给了两个函数,让我发懵了很久。
这里的insert函数主要是在组建字符串,这里是一个字符一个字符给你的,你要把他组起来。
class Solution
{
public:
//Insert one char from stringstream
void Insert(char ch)
{
str += ch;
hash[ch ]++;
}
//return the first appearence once char in current stringstream
char FirstAppearingOnce()
{
int i = 0;
for (i = 0; i < str.size(); i++)
{
if (hash[str[i]] == 1)
return str[i];
}
return '#';
}
int hash[256] = { 0 };
string str;
};
这里我们定义一个string类型的变量用来存储字符串,然后再定义一个哈希映射的数组。这里的思想就是我们把每个字符都映射到一个唯一的数组中的位置,数组中初始值都是0代表着这个数组中的字符都出现了0次,然后获取字符,没获取到一个字符,那就把这个数组中字符对应的位置的数字进行++,变成了几那就说明这个字符串出现了几次。
之后要做的就是去遍历我们的数组,这里要注意的是,我们不能说把这个数组开始从0位置开始遍历,遇到第一个是1的就返回这个数,我们要找的是字符串中第一个出现的字符,所以当然要从字符串第一个开始,我们要找到字符串第一个字符对应的数组中的位置,然后看看是不是1不是的话找字符串中第二个字符对应的映射位置是不是1,以此类推,直到找到是1的那个为止。
for (i = 0; i < str.size(); i++)
{
if (hash[str[i]] == 1)
return str[i];
}
所以这里要格外的注意,i的条件是小于字符串的长度,而不是说256,然后每次访问的不是hash[i]而是hash[str[i]]。
下边是今天的选择题
NumberList是一个顺序容器,以下代码执行后,NumberList里的元素依次为:
List<int> NumberList = new List<int>(){2,4,1,3,5};
for(int i = 0;i<NumberList.Count;++i)
{
int v = NumberList[i];
if(v%2 = = 0)
{
NumberList.Remove(v);//删除的是元素,而非下标
}
}
A.2,4,1,3,5
B.2,1,3,5
C.4,1,3,5
D.1,3,5
这里我初始当然选择的是D,最初还认为这个题目应该是最简单的一个了,虽然当时认为可能会有坑, 但是看来看去也没看到哪里有,所以直接选择了D。正确答案是C
List是STL库中的一个容器, list是一个线性双向链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有序的元素链接起来。由于其结构的原因,list 随机检索的性能非常的不好,因为它不像vector 那样直接找到元素的地址,而是要从头一个一个的顺序查找,这样目标元素越靠后,它的检索时间就越长。检索时间与目标元素的位置成正比。虽然随机检索的速度不够快,但是它可以迅速地在任何节点进行插入和删除操作。因为list 的每个节点保存着它在链表中的位置,插入或删除一个元素仅对最多三个元素有所影响,不像vector 会对操作点之后的所有元素的存储地址都有所影响,这一点是vector 不可比拟的。
list 的特点:
(1) 不使用连续的内存空间这样可以随意地进行动态操作; (2) 可以在内部任何位置快速地插入或删除,当然也可以在两端进行push 和pop 。 (3) 不能进行内部的随机访问,即不支持[ ] 操作符和vector.at() ; (4) 相对于verctor 占用更多的内存。
所以这里我们传入2之后发现2是要被删除的,在删除完之后,因为list是一个顺序容器,所以后边的元素会往前移动那就变成了{4,1,3,5},这时候在进入for循环的时候i已经变成了1,他访问的是1位置的这个元素所以答案选择C。