a. vector b. list c. deque d. map e. set f. multimap g. multiset h. hash table
int a, b, c; int *p, *q, *r;Also suppose that the above variables are assigned the following memory addresses:
a: 0x1000 b: 0x1004 c: 0x1008 p: 0x100c q: 0x1010 r: 0x1014What values are printed by the following two cout statements. Note that the first cout statement prints p and q whereas the second cout statement prints *p and *q.
p = &c; *p = 20; p = &a; *p = 40; q = p; b = *q + *p; cout << a << " " << b << " " << c << " " << p << " " << q << endl; a = 60; b = 20; c = 70; r = &b; b = a + c; p = new int; *p = 2; q = new int; *q = a / *p; cout << a << " " << b << " " << c << " " << *p << " " << *q << " " << *r << endl; cout 1: cout2: a: 40 a: 60 b: 80 b: 130 c: 20 c: 70 p: 0x1000 *p: 2 q: 0x1000 *q: 30 *r: 130
a. memory leak b. dangling pointer c. seg fault
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
-1 | 12 | 23 | 0 | 48 | 35 | -1 | -1 | 30 | -1 | 32 |
int find(vector<int> &hashTable, int key) { unsigned int bucket = key % hashTable.size(); int i; 1 for (i = bucket; i != bucket-1; i = (i+1) % hashTable.size()) { 2 if (hashTable[i] == key) { 3 return i; 4 } 5 } 6 return -1; }
If the key is not in the table, then find performs a linear search of the table, which is an O(n) operation. It should stop as soon as it reaches a bucket that is empty and has never been occupied.
Add the following code segment after line 4:
else if (hashTable[i] == -1) {
return -1;
}
Algorithm 1: T(n) = 1000n*log2n + 20n + 3 Algorithm 2: T(n) = 0.5n2 + 50n + 8
You should choose Algorithm 1 because for large n, Algorithm 1's running time of n*log2n is less than Algorithm 2's running time of n2.
class User { public: string username; string realname; int points; set <string> phone_numbers; }; map <string, User *> Phones;Here are two code segments that correctly remove all of the user's phones from the Phones map:
(a) | (b) |
---|---|
void deletePhones(User *u) { set |
void deletePhones(User *u) { map<string, User*>::iterator phone_it; // phone_it is correctly advanced in the loop body, which is // why there is no phone_it++ as the third expression in the for header for (phone_it = Phones.begin(); phone_it != Phones.end(); ) { if (phone_it->second == u) { phone_it = Phones.erase(phone_it); } else { phone_it++; } } } |
Make the following assumptions:
Answer the following questions:
Code segment a requires at most 5 iterations of its loop body and a remove from a map requires O(log n) time. Hence code segment a requires 5*O(log n) or O(log n) time.
Code segment b requires n iterations of its loop body. Most of the iterations do nothing other than check the pointer to user, which is a constant time operation. At most 5 of the iterations will remove a phone, which requires O(log n) time. Hence the running time of the algorithm is at most T(n) = n + 5*log n, which is O(n).
Since log n is less than n for large n, we prefer code segment a.
list<int> names; list<int>::iterator nit, nit1; names.push_back(45); names.push_back(100); names.push_front(80); names.push_front(50); names.push_front(200); nit = names.begin(); nit++; nit++; nit1 = nit; nit1++; names.erase(nit); nit = nit1; nit++; names.insert(nit, 15); nit1 = names.end(); X --- 200 --- 50 --- 45 --- 15 --- 100 --- X ^ ^ nit nit1
class ListNode { public: string name; ListNode *next; ListNode *prev; ListNode(string n) : name(n) {} };Further suppose that a series of inserts have created the following list:
ListNode *newnode; 1) newnode = new ListNode("Brad"); 2) newnode->next = currentNode; 3) newnode->prev = currentNode->prev; 4) currentNode->prev = newnode; 5) currentNode->prev->next = newnode;
The problem with this code is that line 4 destroys currentNode's prev pointer to "Ben" and makes currentNode's prev pointer point to "Brad". Now when we try to make currentNode's previous node, which was "Ben", point to "Brad", we fail, because currentNode's prev pointer has already been set to point to "Brad". Hence when we try to access currentNode's previous node, we errononeously go to "Brad", and make "Brad"'s next pointer point to itself.
Solution 1: move line 5 before line 4. If line 5 executes before line 4, then currentNode's prev pointer still points to "Ben", and "Ben"'s next pointer is correctly made to point to "Brad".
Solution 2: To avoid these types of code ordering problems, it's best to declare a pointer variable that points to "Ben" before we start any manipulations of the list. Hence in the declaration list we should add the declaration:
ListNode *prevNode = currentNode->prev;Then we can modify line 5 to read:
prevNode->next = newnode;
list<string> *findCaps(list<string> &words) { list<string> *upperCaps = new list<string>(); list<string>::iterator iter; iter = words.begin(); while (iter != words.end()) { if (((*iter)[0] >= 'A') && ((*iter)[0] <= 'Z')) { upperCaps->push_back(*iter); iter = words.erase(iter); } else { iter++; } } return upperCaps; }
void Device::addCustomer(string customerName, string customerAddress) { Customer *newCustomer; newCustomer = new Customer(customerName, customerAddress); customerMap[customerName] = newCustomer; } void Device::addDevice(string deviceName, string customerName) { pair <set<string>::iterator, bool> deviceReturnValue; deviceReturnValue = devices.insert(deviceName); if (deviceReturnValue.second) { customerMap[customerName]->devices.insert(deviceName); } } void Device::printCustomers() { map<string, Customer *>::iterator mapIter; set<string>::iterator setIter; Customer *customer; for (mapIter = customerMap.begin(); mapIter != customerMap.end(); mapIter++) { customer = mapIter->second; printf("%-15s %-30s\n", customer->name.c_str(), customer->address.c_str()); for (setIter = customer->devices.begin(); setIter != customer->devices.end(); setIter++) { printf(" %s\n", (*setIter).c_str()); } } }