Related
I'd like to create a method that takes two arguments: List of string and pointer to list element. Next, I would like to delete the list item pointed to by the pointer.
Firstly i create simple list:
list<string> list_ptr = { "1", "2", "3", "4", "5", "6", "7", "8"};
I suppose that i first should check element exist:
auto it = find(list_ptr.begin(), list_ptr.end(), "4");
And if element exist, get his pointer and call function delete:
void delete(node_t *list_ptr, node_t *p)
My problem is that I have no idea if it is even possible to delete a list item using its pointer. Additionally, how can I get the indicator of a single list item?
Yes, I am C++ newbie :)
std::list has its own interface for deleting, sorting, etc:
#include <stdio.h>
#include <list>
#include <string>
int main() {
std::list<std::string> strlist = {"1", "2", "3", "4", "5", "6", "7", "8"};
strlist.remove("4");
for (auto const& elm : strlist) puts(elm.c_str());
}
If you want to use the iterators like in your example, here's how you do it:
std::list<std::string> strlist = {"1", "2", "3", "4", "5", "6", "7", "8"};
auto it = std::find(strlist.begin(), strlist.end(), "4");
if (it != strlist.end()) strlist.erase(it);
On that note, if preserving the ordering is not a concern for you, you can have efficient O(1) removal from anywhere in std::vector, which is generally a better containier:
#include <stdio.h>
#include <algorithm>
#include <iterator>
#include <string>
#include <vector>
int main() {
std::vector<std::string> strvec = {"1", "2", "3", "4", "5", "6", "7", "8"};
auto it = std::find(strvec.begin(), strvec.end(), "4");
if (it != strvec.end()) {
std::iter_swap(it, std::prev(strvec.end()));
strvec.pop_back();
}
for (auto const& elm : strvec) puts(elm.c_str());
}
Assuming I have a
val s: String = "14ABC5"
and have a HashMap
val b: HashMap<String,String> = hashMapOf("A" to "10", "B" to "11", "C" to "12", "D" to "13", "E" to "14", "F" to "15" )
How would I change all occurrences of A,B,C with 10, 11, 12 while keeping their order ("1", "4", "10", "11", "12", "5")?
So far I have this
val result: List<String> = s.toUpperCase().toCharArray().map{ it.toString() }.map{ it -> b.getValue(it)}
which works if ALL characters of the String exist in the HashMap but my String may contain inexistent keys as well.
You could either use getOrDefault(...), or the Kotlinesque b[it] ?: it.
By the way, if you're using the implicit lambda argument name (it), you can get rid of the it ->.
You can use the String as an iterable by default and simplify your code as follows:
s.map { it.toString() }
.map { b[it] ?: it }
If I have two map<string, int>s how can I swap an element from each map?
For example:
map<string, int> ps{ { "triangle", 0 }, { "cross", 1 }, { "square", 2 }, { "circle", 3 } };
map<string, int> xbox{ { "y", 0 }, { "a", 1 }, { "b", 2 }, { "x", 3 } };
swap(move(ps["cross"]), move(xbox["x"]));
The swap statement is clearly wrong, but that explains what I want to do. After the swap statement I'd like ps to contain:
{ "triangle", 0 }
{ "x", 3 }
{ "square", 2 }
{ "circle", 3 }
And xbox to contain:
{ "y", 0 }
{ "a", 1 }
{ "b", 2 }
{ "cross", 1 }
I expect there is a good way to do this with C++11's move syntax, but if possible I'd like an answer that also describes how to accomplish this on C++03.
map is implemented as an ordered tree.
You cannot simply replace a key with a new key as it might have to be placed on a different location in the tree. Consequently, you cannot swap.
Delete an re-insert the k-v pairs manually.
(As a sidenote: you haven't even told us what happens with the values...)
I'm expecting this code to print spade:A spade:2 and so on until heart:K.
But it only does heart:A to heart:K.
How should I do it?
symbols = ["spade", "clover", "diamond", "heart"]
numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
cards = {}
for num in numbers:
for symbol in symbols:
cards[num] = symbol
print cards
Use your itertools toolbox
import itertools
symbols = ["spade", "clover", "diamond", "heart"]
numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
combinations = itertools.product(symbols, numbers)
cards = ["{}:{}".format(suit, rank) for suit,rank in combinations]
This will give you the list:
['spade:A',
'spade:2',
'spade:3',
'spade:4',
'spade:5',
'spade:6',
'spade:7',
'spade:8',
'spade:9',
'spade:10',
'spade:J',
'spade:Q',
'spade:K',
'clover:A',
'clover:2',
'clover:3',
'clover:4',
'clover:5',
'clover:6',
'clover:7',
'clover:8',
'clover:9',
'clover:10',
'clover:J',
'clover:Q',
'clover:K',
'diamond:A',
'diamond:2',
'diamond:3',
'diamond:4',
'diamond:5',
'diamond:6',
'diamond:7',
'diamond:8',
'diamond:9',
'diamond:10',
'diamond:J',
'diamond:Q',
'diamond:K',
'heart:A',
'heart:2',
'heart:3',
'heart:4',
'heart:5',
'heart:6',
'heart:7',
'heart:8',
'heart:9',
'heart:10',
'heart:J',
'heart:Q',
'heart:K']
The problem is that you are not iterating the right way and thus you are not appending in the list. The right way to do it is
symbols = ["spade", "clover", "diamond", "heart"]
numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
cards = []
for j in range(len(symbols)):
for i in range(len(numbers)):
cards.append(str(symbols[j]+':'+str(numbers[i])))
print cards
with output:
['spade:A', 'spade:2', 'spade:3', 'spade:4', 'spade:5', 'spade:6', 'spade:7', 'spade:8',
'spade:9', 'spade:10', 'spade:J', 'spade:Q', 'spade:K', 'clover:A', 'clover:2',
'clover:3', 'clover:4', 'clover:5', 'clover:6', 'clover:7', 'clover:8', 'clover:9',
'clover:10', 'clover:J', 'clover:Q', 'clover:K', 'diamond:A', 'diamond:2', 'diamond:3',
'diamond:4', 'diamond:5', 'diamond:6', 'diamond:7', 'diamond:8', 'diamond:9', 'diamond:10',
'diamond:J', 'diamond:Q', 'diamond:K', 'heart:A', 'heart:2', 'heart:3', 'heart:4',
'heart:5', 'heart:6', 'heart:7', 'heart:8', 'heart:9', 'heart:10', 'heart:J', 'heart:Q', 'heart:K']
Made with Ipython Notebook in python 2.7
Hope it helps.
You are iterating the symbols just fine but when you are going over the numbers in the second loop, you are actually replacing the values set by the previous loop hence you only have values from the last loop left and everything is replaced. This means cards["A"] value is set 4 times in the loop and the last for the "heart" is retained. The same thing is happening for all the other indexes.
This question already has answers here:
Do jagged arrays exist in C/C++?
(12 answers)
Closed 8 years ago.
Is there a way to initialize two dimensional array with different size of columns in c++?
I try to make console card game.
I have done something like this while ago.
static string const group[7][];
string const Cards::group = {
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
It doesn't work.
It would be great if an array would be additionally static and constant but it isn't necessary. The most important thing is to make code works.
I would be grateful for any kind of help.
Arrays in C++ are not truly dynamic; they cannot be extended nor reduced in size. Moreover, the dimensions of static arrays have to be known at their declaration. Dynamically-allocated arrays can be used by declaring group as a string** and later initializing it with the appropriately-sized memory. You can also use a 2-dimensional vector which is fundamentally equivalent but preferred because it is cleaner because we can leverage its memory management:
static std::vector<std::vector<std::string>> const group;
std::vector<std::vector<std::string>> Cards::group = {
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
You can't use:
string group[7][] =
However, you can use:
std::vector<std::string> group[] =
Here's a working program.
#include <iostream>
#include <string>
#include <vector>
std::vector<std::string> group[] =
{
{ "AA", "KK", "AKs" },
{ "QQ", "JJ", "AK", "AJs", "KQs", "AQs" },
{ "TT", "AQ", "ATs", "KJs", "QJs", "JTs" },
{ "99", "88", "AJ", "AT", "KQ", "KTs", "QTs", "J9s" , "T9s" , "98s" },
{ "77", "66", "A9s", "A5s", "A4s", "A3s", "A2s", "K9s", "KJ", "KT", "QJ", "QT", "Q9s", "JT", "QJ", "T8s", "97s", "87s", "76s", "65s"},
{ "55", "44", "33", "22", "K9", "J9", "86s"},
{ "T9", "98", "85s"}
};
int main()
{
for ( auto it1 : group )
{
for ( auto it2 : it1 )
{
std::cout << it2 << " ";
}
std::cout << std::endl;
}
}
You cannot do
string group[7][];
Instead, you can only do
string group[][7];
for multidimensional C-style arrays.
If you truly need multidimensional array with different sizes in the last dimension, you can use std::vector> with STL.