describe
Assuming that the single linked list of the leading node is used to save words, when two words have the same suffix, they can share the same suffix space. For example, the storage images of "loading" and "being" are shown in the following figure:
Let str1 and str2 respectively point to the head node of the single linked list where the two words are located. Please implement an algorithm as efficient as possible in time, find the node at the starting position of the common suffix of the two linked lists referred to by str1 and str2, and output the character corresponding to the node (as shown in character i in the figure)
input
Multiple groups of data. Each group of data has three rows. The first row is the length N and m of the linked list str1 and str2, the second row is the n elements of the linked list str1, and the third row is the m elements of the linked list str2 (the elements are separated by spaces). Input ends when n=0 and m=0.
output
For each group of data, one line is output, which is the character corresponding to the starting position node of the common suffix.
Input sample 1
7 5 l o a d i n g b e i n g 7 9 f l u e n c y f r e q u e n c y 0 0
Output sample 1
i u
Idea:
Looking at the title means that the problem has been simplified. The suffixes of the two words given must be the same. There will be no case where one suffix contains another suffix - that is, similar to
kianana kianame
At the same time, after testing,
1 1 i i 0 0
Such extremes were not detected. But it should be taken into account, hiahiaha~
Idea:
I use the single linked list for this question. If it is a single linked list, it is better to use the head interpolation method, because the head interpolation method does not need to consider the kianana test case mentioned above; Moreover, it is known that a string of characters at the end must correspond one by one, so there is no need to consider the problem of "one fast and one slow" during traversal if the two words are not the same length, which is equivalent to tail alignment. In short, I think head interpolation is the best choice for single linked list.
I directly pass the Find function to the initial node, and this is a one-time traversal. The nodes that have been compared need not be managed, so there is no need for another p - > next.
In the Find function, t is used to save the data of the initial node transmitted for the first time. It is written to initialize the string at the beginning, and it will change when looping later. temp is used to save the letter to be output.
Let's simulate the cycle process to
7 5 l o a d i n g b e i n g
For example.
1.0 t=g
1.1 l1->data==l2->data=g, temp=l1->data=g
1.2 t=g
1.3 l1 = l1->next;
l2 = l2->next;
2.1 temp=l1->data=n
2.2 t=l1->data=n
2.3 l1 = l1->next;
l2 = l2->next;
3.1 temp=l1->data=i
3.2 t=l1->data=i
3.3 l1 = l1->next;
l2 = l2->next;
4.1 temp=t=i
4.2 cout<<temp<<endl;break;
Of course, it is easier to output with a two-way linked list. You can easily find the value to output with prior~
#include<string> #include<iostream> #include<map> #include<vector> #include<cmath> #include<set> #include<algorithm> using namespace std; typedef struct LNode { string data; LNode* next; }*linklist, LNode; void TInsert(linklist& l, int n) { l = new LNode; l->next = NULL; for (int i = 0; i < n; i++) { linklist p = new LNode; cin >> p->data; p->next = l->next; l->next = p; } } void Find(linklist l1, linklist l2) { string t = l1->data; while (l1 && l2) { string temp = l1->data == l2->data ? l1->data :t ; if ((l1->data != l2->data)|| (l1->next == NULL && l2->next == NULL)) { cout << temp << endl; break; } t = l1->data; l1 = l1->next; l2 = l2->next; } } int main() { int n1,n2; cin >> n1>>n2 ; while (n1&&n2) { linklist s1,s2; TInsert(s1,n1); TInsert(s2, n2); Find(s1->next, s2->next); cin >> n1 >> n2; } return 0; }
The two-way linked list code is as follows. The use case 1 I I can also output the correct value (although the system has no card, this = v =)
#include<string> #include<iostream> #include<map> #include<vector> #include<cmath> #include<set> #include<algorithm> using namespace std; typedef struct LNode { string data; LNode* next; LNode* prior; }*linklist, LNode; void TInsert(linklist& l, int n) { l = new LNode; l->next = NULL; cin >> l->data; linklist head = l; for (int i = 1; i < n; i++) { linklist p = new LNode; cin >> p->data; p->next = head; head->prior = p; head = p; } l->next = head; head->prior = l; } void Find(linklist l1, linklist l2) { while (l1 && l2) { string temp = l1->data == l2->data ? l1->data :l1->prior->data; if ((l1->data != l2->data) || (l1->next == l1 && l2->next == l2)) //You can't write = = NULL here~ { cout << temp << endl; break; } l1 = l1->next; l2 = l2->next; } } int main() { int n1,n2; cin >> n1>>n2 ; while (n1&&n2) { linklist s1,s2; TInsert(s1,n1); TInsert(s2, n2); Find(s1->next, s2->next); cin >> n1 >> n2; } return 0; }