c++ Deleting duplicated Names in array - c++

EDIT: Thank you so much everyone, songyuanyao Answered my question, and you guys did lol but i didnt know some codes u put and im sure soon i will learn them :) thanks again.
i really have a question about removing duplicated Names in a string, note that im fairly new to c++, anyways i'll get to the point.
what im trying to do is removing duplicated names in an array, the code below is working fine but here's what im facing.
For example i entered 4 names: (Hana, Alex, Hana, Alex) the results that i want to get is just : ( Hana and Alex) while the other 2 names should be removed yet what im getting is ( Hana , Alex, Alex).
im really confused about what should i do to fix this and i want it to check every name in the list, Thanks in advance :).
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
string nurse[4];
int i, n=3, j, k, num;
int main()
{
cout << "Please Enter names to add to the list --->";
for (i = 0; i <= n; i++)
{
cin >> nurse[i];
}
for (int i = 0; i < n; i++)
{
for (j = i + 1; j < n;)
if (nurse[j] == nurse[i])
{
for (k = j; k < n; k++)
{
nurse[k] = nurse[k + 1];
}
n--;
}
else
{
j++;
}
}
cout << "Printing list after removing duplicated names" << endl;
for (i = 0; i <= n; i++)
cout << " "<<nurse[i] << endl;
system("pause");
return 0;
}

#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// ...
vector<string> nurses;
nurses.push_back("Hana");
nurses.push_back("Alex");
nurses.push_back("Hana");
nurses.push_back("Alex");
sort(nurses.begin(), nurses.end());
const vector<string>::iterator it = unique(nurses.begin(), nurses.end());
nurses.erase(it, nurses.end());

Say you start with
vector<string> v{"alex", "emma", "alex"};
Define an unordered_set with these items:
unordered_set<string> h;
Now use the erase-remove idiom using
[&h](const string &s){return !h.insert(s).second;};
This will do the job in (expected) linear time.
Full example:
#include <string>
#include<vector>
#include <unordered_set>
#include <algorithm>
using namespace std;
int main()
{
vector<string> v{"alex", "emma", "alex"};
unordered_set<string> h;
auto r = [&h](const string &s){return !h.insert(s).second;};
v.erase(remove_if(begin(v), end(v), r), end(v));
}

You condition in for is one less than the count of the elements, so the last element won't be checked at all.
for (int i = 0; i <= n; i++)
~
{
for (j = i + 1; j <= n;)
~
if (nurse[j] == nurse[i])
{
for (k = j; k <= n; k++)
~
{
nurse[k] = nurse[k + 1];
}
n--;
}
else
{
j++;
}
}

You are effectively not removing names from your array. You are just shifting them in case same name comes!
You could actually use a std::set which will automatically do this for you!
std::set< std::string > nurses;
std::string nurse;
for (i = 0; i <= n; i++)
{
std::cin >> nurse;
nurses.insert( nurse );
}
Do not forget to include <set> in your code.

Related

I am trying to sort the map in decreasing order but i am not getting the desired result?

#include <iostream>
#include <string>
#include <map>
using namespace std;
typedef long long int ll;
int main()
{
string s;
cin >> s;
map<char, int,greater <int>> m;
m['A'] = 1;
m['C'] = 1;
m['G'] = 1;
m['T'] = 1;
for(ll i = 0; i < s.length()-1; i++)
{
if(s[i] == s[i+1]) //ATTCGGGA
m[s[i]]++;
}
for(auto it = m.begin(); it != m.end(); it++)
{
cout <<it->first <<" " <<it->second<<endl;
}
//cout <<it->second<<endl;
return 0;
}
my desired output should be
G 3
T 2
A 1
C 1
but its showing
T 2
G 3
C 1
A 1
I dont know why this is happening as i have already mentioned it to be greater in the orderedmap.
Please kindly solve the issue?
you could just simply use a queue.
If you want to do it with a map use a multi_map(); and use the int as the key and the char as the value that way u will sort them according to the int value

Function not printing any solutions

So, I need to make a function that is going to return the chromatic number of a graph. The graph is given through an adjecency matrix that the function finds using a file name. I have a function that should in theory work and which the compiler is throwing no issues for, yet when I run it, it simply prints out an empty line and ends the program.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
int Find_Chromatic_Number (vector <vector <int>> matg, int matc[], int n) {
if (n == 0) {
return 0;
}
int result, i, j;
result = 0;
for (i = 0; i < n; i++) {
for (j = i; j < n; j++) {
if (matg[i][j] == 1) {
if (matc[i] == matc[j]) {
matc[j]++;
}
}
}
}
for (i = 0; i < n; i++) {
if (result < matc[i]) {
result = matc[i];
}
}
return result;
}
int main() {
string file;
int n, i, j, m;
cout << "unesite ime datoteke: " << endl;
cin >> file;
ifstream reader;
reader.open(file.c_str());
reader >> n;
vector<vector<int>> matg(n, vector<int>(0));
int matc[n];
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
reader >> matg[i][j];
}
matc[i] = 1;
}
int result = Find_Chromatic_Number(matg, matc, n);
cout << result << endl;
return 0;
}
The program is supposed to use an freader to convert the file into a 2D vector which represents the adjecency matrix (matg). I also made an array (matc) which represents the value of each vertice, with different numbers corresponding to different colors.
The function should go through the vector and every time there is an edge between two vertices it should check if their color value in matc is the same. If it is, it ups the second vale (j) by one. After the function has passed through the vector, the matc array should contain n different number with the highest number being the chromatic number I am looking for.
I hope I have explained enough of what I am trying to accomplish, if not just ask and I will add any further explanations.
Try to make it like that.
Don't choose a size for your vector
vector<vector<int> > matg;
And instead of using reader >> matg[i][j];
use:
int tmp;
reader >> tmp;
matg[i].push_back(tmp);

C++: Should I implement stack / queue / deque by array to improve performance?

I've just solved a problem on SPOJ, I do DFS and use STL stack instead of recursive, I got TLE. Then i use array stack instead of STL stack and got Accepted.
The problem is : Give an n*n table, each square have a number. First, you can start at any square, choose a number K.Then you can go to squares that have a common edge with the square you stand, and abs( number on that square - number on the square you stand) == K. What is the biggest area that you can go ?
This is my solution :
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <utility>
#include <cmath>
#include <cstring>
#include <stack>
using namespace std;
#define maxn 1010
int n, a[maxn][maxn],visited[maxn][maxn], direction[5][3],cnt,anscnt,dd[1000010],dc[1000010],k[1000010];
bool Free[maxn][maxn][5];
/*void visit(int d,int c,int dif) {
stack<int> dd,dc,k;
dd.push(d);
dc.push(c);
k.push(1);
visited[d][c]=dif;
cnt = 0;
while (!dd.empty()) {
int ud = dd.top(), uc = dc.top() , i = k.top();
k.pop();
for (;i<=4;i++)
if (Free[ud][uc][i]) {
int vd = ud+direction[i][1], vc = uc + direction[i][2];
if ((vd==0) or (vc==0) or (vd>n) or (vc>n)) continue;
if ((visited[vd][vc]==dif) or (abs(a[vd][vc]-a[ud][uc])!=dif)) continue;
if (Free[vd][vc][5-i]==false) continue;
visited[vd][vc]=dif;
Free[vd][vc][5-i]=false;
Free[ud][uc][i]=false;
k.push(i+1);
dd.push(vd);
dc.push(vc);
k.push(1);
break;
}
if (i==5) {
cnt++;
cout << ud << ' ' << uc << ' ' << dd.top() << ' ' << dc.top() << ' ' << dd.size() << '\n';
dd.pop(); dc.pop();
}
}
if (cnt > anscnt) {anscnt = cnt;}
} */
void visit(int d,int c,int dif) {
int topdd=0, topdc=0, topk=0;
dd[++topdd]=d;
dc[++topdc]=c;
k[++topk]=1;
visited[d][c]=dif;
cnt = 0;
while (topdd>0) {
int ud = dd[topdd], uc = dc[topdc] , i = k[topk];
topk--;
for (;i<=4;i++)
if (Free[ud][uc][i]) {
int vd = ud+direction[i][1], vc = uc + direction[i][2];
if ((vd==0) or (vc==0) or (vd>n) or (vc>n)) continue;
if ((visited[vd][vc]==dif) or (abs(a[vd][vc]-a[ud][uc])!=dif)) continue;
if (Free[vd][vc][5-i]==false) continue;
visited[vd][vc]=dif;
Free[vd][vc][5-i]=false;
Free[ud][uc][i]=false;
k[++topk]=(i+1);
dd[++topdd]=(vd);
dc[++topdc]=(vc);
k[++topk]=(1);
break;
}
if (i==5) {
cnt++;
topdd--; topdc--;
}
}
if (cnt > anscnt) {anscnt = cnt;}
}
int main()
{
std::ios_base::sync_with_stdio(false);
anscnt = 1;
direction[1][1] = -1; direction[1][2] = 0;
direction[2][1] = 0; direction[2][2] = 1;
direction[3][1] = 0; direction[3][2] = -1;
direction[4][1] = 1; direction[4][2] = 0;
cin >> n;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) cin >> a[i][j];
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) visited[i][j]=-1;
memset(Free,true,sizeof(Free));
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++) {
if (i>1) visit(i,j,abs(a[i][j]-a[i-1][j]));
if (j<n) visit(i,j,abs(a[i][j]-a[i][j+1]));
if (j>1) visit(i,j,abs(a[i][j]-a[i][j-1]));
if (i<n) visit(i,j,abs(a[i][j]-a[i+1][j]));
}
cout << anscnt;
}
http://ideone.com/Hn6Dl4
When n = 1000, and all square in table = 0, STL stack is more than 2s and array stack is less than 1s.
So i think STL implementation of stack is slower than implementing stack by array. Queue, deque also can be implemented by array too.
Why is STL implementation slower and should i implement them by array to improve performane ?
As usual you should always use direct memory access (like arrays) in simple cases or implement your own data structure for complex cases for better perfomance. Std containers have checks, inderections and throw exceptions that decrease memory access perfomance. Moreover in your algorithm in 'stack' version you use methods to increase/decrease stack size, that can (but not must) cause large amout of memory allocation/deallocation that also leads to perfomance issues.

How to Generate Permutations With Repeated Characters

I basically want to create strings that consist of three operation symbols (eg: +-* or ++/ or +++). Each one of these strings should be pushed into vector <string> opPermutations
This is my code so far:
// Set up permutations for operators
string operatorBank[4] = {"+","-","*","/"};
do {
string currentPerm = operatorBank[0] + operatorBank[1] + operatorBank[2] + operatorBank[3];
this -> opPermutations.push_back(currentPerm);
} while ( std::next_permutation(operatorBank, operatorBank + 4) );
The permutations that are pushed into the vector (as strings) are:
+-*/
+-/*
+/*-
+/-*
-*+/
-*/+
-+*/
-+/*
-/*+
-/+*
/*+-
/*-+
/+*-
/+-*
/-*+
/-+*
What I want however is to have my permutations exist like this:
Each should be three characters in length
Every possible permutation, including the ones in which a character is repeated more than one time, must be present.
I want it to be organized as such:
+++
---
***
///
/*/
+-+
++*
**/
etc...
How can I achieve this?
Using the recursion to print what you asked. Adapting it to store permutation string in vectors should be trivial. I am not a c++ programmer,so there may be better way to do it in C++. but the main idea here is to use recursion.
#include <iostream>
#include <string>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void displayPermutation(string permutation[], int length){
int i;
for (i=0;i<length;i++){
cout<<permutation[i];
}
cout << endl;
}
void getPermutations(string operatorBank[], int operatorCount,
string permutation[],int permutationLength, int curIndex){
int i;
//stop recursion condition
if(curIndex == permutationLength){
displayPermutation(permutation,permutationLength);
}
else{
for(i = 0; i < operatorCount; i++){
permutation[curIndex] = operatorBank[i];
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex+1);
}
}
}
int main ()
{
int operatorCount = 4;
int permutationLength = 3;
string operatorBank[] = {"+","-","*","/"};
string permutation[] = {"","","",""}; //empty string
int curIndex = 0;
getPermutations(operatorBank,operatorCount,permutation,
permutationLength,curIndex);
return 0;
}
output:
+++
++-
++*
++/
+-+
+--
+-*
+-/
+*+
+*-
+**
+*/
+/+
+/-
+/*
+//
.
.
and so on.
Strings with repeated elements are not possible permutations, because a permutation is an ordering.
You can do this with 3 nested for loops as wlyles said.
Edited to add:
This will print the strings I think you want. You can replace the cout statement with opPermutations.push_back(operatorBank[i]+operatorBank[j]+operatorBank[k]) to add to the vector.
#include <iostream>
#include <string>
int main(){
std::string operatorBank[4] = {"+","-","*","/"};
for (int i=0; i<4; ++i){
for (int j=0; j<4; ++j){
for (int k=0; k<4; ++k){
std::cout << operatorBank[i] << operatorBank[j] << operatorBank[k] << std::endl;
}
}
}
return 0;
}
I think maybe the confusion is over the term "permutation." You could get the same strings as 3-permutations of the set {"+","+","+","-","-","-","*","*","*","/","/","/"} but using loops seems simpler to me.
Easiest way to generate permutations is Set Product ..
list<string> setProduct (list<string> a, list<string> b)
{
list<string> L;
list<string>::iterator i, j;
for(i = a.begin(); i != a.end(); ++i)
for(j = b.begin(); j != b.end(); ++j)
L.push_front(*i + *j);
return L;
}
list<string> permute (list<string> a, int len)
{
list<string> L;
while (len --> 0) L.splice(a.end(), setProduct(L,a));
return L;
}

C++ sorting vector strings not working

For some reason I cannot get this sort the names correctly. Can anyone tell me what is wrong with it? As far as I can tell the problem is that the strings are not compared correctly. I have tried string comparisons before, and I know this kind of code should work. It really has me stumped.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
void sortNames(vector<string> &);
void main()
{
vector<string> namesList;
ifstream namesFile;
namesFile.open("Names.txt");
// Make sure the file exists.
if (namesFile)
{
// Get the names from the file.
string name;
while (getline(namesFile, name))
namesList.push_back(name);
// Sort the imported names.
sortNames(namesList);
for (int i = 0; i < namesList.size(); i++)
cout << namesList[i] << endl;
}
else
{
cout << "Data files are missing";
}
namesFile.close();
}
void sortNames(vector<string> &list)
{
for (int i = 0; i < list.size(); i++)
{
// Find the lowest value after i.
int lowIndex = i;
for (int j = i + 1; j < list.size(); j++)
{
string name = list[i];
string name2 = list[j];
if (name > name2)
lowIndex = j;
}
// Flip the elements if there was a value lower than i.
if (i != lowIndex)
{
string temp = list[i];
list[i] = list[lowIndex];
list[lowIndex] = temp;
}
}
}
Here is the problem: this line
string name = list[i];
should be
string name = list[lowIndex];
Your current implementation compares the element at j not to the smallest string that you have found so far, but to the string at index i. That is incorrect, because it does not find the smallest remaining string: instead, it finds the last string in the vector that is smaller than the current element at index i, which is not what you want.
rather than string name = list[i];, you want string name = list[lowIndex];