Delete list element using element pointer - c++

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());
}

Related

Flutter List Behaviour is not as expected

I am making a filtering system in flutter by using two lists called mailList and filteredMailList. The first time mailList is populated, this code runs:
setState(() {
filteredMailList.clear();
filteredMailList = mailList;
});
When this has been done, it seems as though any changes that I make on mailList get replicated to filteredMailList even though I haven't executed those two lines again. For example:
//Assume that mailList = ["1", "2", "3"] and filteredMailList = []
filteredMailList = mailList
//I expect then mailList = ["1", "2", "3"] and filteredMailList = ["1", "2", "3"]
mailList.add("4")
//I expect then mailList = ["1", "2", "3", "4"] and filteredMailList = ["1", "2", "3"]
//However when this is run mailList = ["1", "2", "3", "4"] and filteredMailList = ["1", "2", "3", "4"]
Does this have something to do with the fact that I might not be giving both lists the same contents, but instead saying that they are referencing the same list?
Is there a way to make filteredMailList only contain the elements of mailList and not actually reference the exact same list, so each one can still be edited independently?
in your code by calling filteredMailList = mailList; you are actually removing your original filteredMailList List (you don't have any refrence to that list anymore) and changing it to the mailList. so both filteredMailList and mailList points to a single List in memory
you can create a clone list from mailList like :
filteredMailList = [...mailList]; // or filteredMailList = mailList.toList();
or keep your original refrence and copy all items from mailList
filteredMailList.clear();
filteredMailList.addAll(mailList);

How do I swap some characters of a String with values of a HashMap<String,String> in Kotlin?

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 }

How to access the arrays in private class of C++?

class bus {
private:
string arr[10] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
public:
void reservation();
};
Here, I have a private array that I want to access and make changes through the reservation() in public class.
void bus::reservaton() {
cout << "What should I write in here to change the 3rd and 7th index of the
above array to \"not empty\"" << endl;
}
Suppose, I want to make the 3rd and 7th index to "not empty", what should I write there?
Sample:-
string arr[10] = { "0", "1", "2", "not empty", "4", "5", "6", "not empty", "8", "9" };
And do I need to make any changes in the main function? If yes, then can you please help me by writing it down.
Thank you.
How to use arrays
void bus::reservation() {
arr[3] = "not empty";
arr[7] = "not empty";
}
For this, a simple assignment operator (=) would work.
For example, in the following example, the value at index 1 is changed:
std::string slist[ 3 ] { "a", "b", "c" };
slist[ 1 ] = "Changed!";
Live example: http://ideone.com/rO9hwt
BTW, you should use std::vector of std::string instead of an array. And, take a look at its member function at() for accessing the value of an index with out of bounds checking.
Live example: http://ideone.com/bcHZpY

Python list and for loop

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.

Initialize two dimensional array with different columns sizes in c++ [duplicate]

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.