How to alphabetically sort strings? - c++

I have been trying to use this c++ program to sort 5 names alphabetically:
#include <iostream>
#include <cstring>
#include <conio.h>
using namespace std;
int main()
{
char names[5][100];
int x,y,z;
char exchange[100];
cout << "Enter five names...\n";
for(x=1;x<=5;x++)
{
cout << x << ". ";
cin >> names[x-1];
}
getch();
for(x=0;x<=5-2;x++)
{
for(y=0;y<=5-2;y++)
{
for(z=0;z<=99;z++)
{
if(int(names[y][z])>int(names[y+1][z]))
{
strcpy(exchange,names[y]);
strcpy(names[y],names[y+1]);
strcpy(names[y+1],exchange);
break;
}
}
}
}
for(x=0;x<=5-1;x++)
cout << names[x];
return 0;
}
If I enter Earl, Don, Chris, Bill, and Andy respectively, I get this:
AndyEarlDonChrisBill
Could someone please tell me whats wrong with my program?

You could use std::set or std::multiset (if you will allow repeated items) of strings, and it will keep the items sorted automatically (you could even change the sorting criteria if you want).
#include <iostream>
#include <set>
#include <algorithm>
void print(const std::string& item)
{
std::cout << item << std::endl;
}
int main()
{
std::set<std::string> sortedItems;
for(int i = 1; i <= 5; ++i)
{
std::string name;
std::cout << i << ". ";
std::cin >> name;
sortedItems.insert(name);
}
std::for_each(sortedItems.begin(), sortedItems.end(), &print);
return 0;
}
input:
Gerardo
Carlos
Kamilo
Angel
Bosco
output:
Angel
Bosco
Carlos
Gerardo
Kamilo

You can use the sort function:
#include <algorithm>
#include <vector>
using namespace std;
...
vector<string> s;
sort(s.begin(),s.end());

You are using too much unnecessary loops. Try this simple and efficient one. You need to just swap when a string is alphabetically latter than other string.
Input
5
Ashadullah
Shawon
Shakib
Aaaakash
Ideone
Output
Aaaakash
Ashadullah
Ideone
Shakib
Shawon
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s[200],x[200],ct,dt;
int i,j,n;
cin>>n;
for(i=0;i<n;i++)
{
cin>>s[i];
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(s[i]>s[j])
{
ct=s[i];
s[i]=s[j];
s[j]=ct;
}
}
}
cout<<"Sorted Name in Dictionary Order"<<endl;
for(i=0;i<n;i++)
{
cout<<s[i]<<endl;
}
return 0;
}

Your code implements a single-pass of bubble sort. Essentially missing the 'repeat until no changes are made to the array' loop around the outside.

The code does not take care when the names are already in order. Add the following
else if(int(names[y][z])<int(names[y+1][z]))
break;
To the if statement.

Putting this here in case someone needs a different solution.
/* sorting example */
#include <iostream>
using namespace std;
bool isSwap( string str1, string str2, int i)
{
if(str1[i] > str2[i])
return true;
if(str1[i] == str2[i])
return isSwap(str1,str2,i+1);
return false;
}
int main()
{
string str[7] = {"you","your","must","mike", "jack", "jesus","god"};
int strlen = 7;
string temp;
int i = 0;
int j = 0;
bool changed = false;
while(i < strlen-1)
{
changed = false;
j = i+1;
while(j < strlen)
{
if(isSwap(str[i],str[j],0))
{
temp = str[i];
str[i] = str[j];
str[j] = temp;
changed = true;
}
j++;
}
if(changed)
i = 0;
else
i++;
}
for(i = 0; i < strlen; i++)
cout << str[i] << endl;
return 0;
}

Related

Struct doesn't print with cout

I'm trying to print the structure in an array whose int prejetih member is highest.
#include <iostream>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(Tekma tekme[]) {
int maksi = 0, index = 0;
for (int i = 0;i < 2;i++) {
if (maksi < tekme[i].prejetih) {
index = i;
maksi = tekme[i].prejetih;
}
}
return tekme[index];
}
void vpis(Tekma tekme[]) {
for (int i = 0;i < 2;i++)
cin >> tekme[i].prejetih;
}
int main() {
Tekma tekme[2];
vpis(tekme);
cout << najvec_kosev(tekme);
}
The compiler reports
C++ no operator matches these operands
operand types are: std::ostream << Tekma
over cout << najvec_kosev(tekme);
Here using a solution with std::vector and fixing your cout problem:
#include <iostream>
#include <vector>
using namespace std;
struct Tekma {
int prejetih;
};
Tekma najvec_kosev(vector<Tekma>& tekme) {
Tekma lowest = tekme[0]
for(auto& t : tekme) {
if(lowest.prejetih < t.prejetih) {
lowest = t;
}
}
return lowest ;
}
void vpis(vector<Tekma>& tekme) {
int input;
while(true) {
cin >> input;
// Check if the input is valid else quit the loop.
if(input == valid) {
Tekma newStruct = {input};
tekme.push(newStruct);
}
else {
// Stop the loop
break;
}
}
}
int main() {
vector<Tekma> tekme;
vpis(tekme);
cout << najvec_kosev(tekme).prejetih; // This fixes your error.
}

Initialization difference between static and dynamic allocation

I'm trying to find what is the difference between the static and the dynamic allocation of the table in this code, I'm interested most about the initial state or values n that table.
when I tried the code with the static allocation the program didn't work and i can see that the table contain random value but with the dynamic allocation it works better.
can someone explain to me how this work thanks.
#include <string>
#include <stdio.h>
#include <iostream>
using namespace std ;
bool isUnique(std::string s)
{
if(s.length()> 128 ) return false;
//bool lettre[128];
bool* lettre = new bool[128];
for (int i = 0; i < s.length(); i++)
{
int index = s[i];
if (lettre[index] == true)
return false;
lettre[index] = true;
}
for(int i=0; i<128;i++)
{
cout<< lettre[i] +" |";
}
cout<<endl;
return true;
}
int main()
{
std::string s1 = "adcadef";
std::string s2 = "abcdef";
cout<< isUnique(s1) << endl;
cout << isUnique(s2) << endl;
return 0;
}

How do I find if two strings is isomorphic of not?

#include <iostream>
#include <string>
#include <vector>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
vector<int> diff_arr(26, -40);//Initialise with some random value.
for(int i = 0 ; i < input1.length(); i++){
if(diff_arr[input1[i]-'a'] == -40)
diff_arr[input1[i]-'a'] = input1[i] - input2[i];
else{
if(diff_arr[input1[i]-'a'] != input1[i] - input2[i])
return false;
}
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
My logic is that if characaters could be replaced with exact same characters in the second string then the character-wise difference has to be the same throughout.
The logic is failing in the above case.
You also need to check if two characters from input1 do not map to same character in input2.
#include <iostream>
#include <string>
#include <map>
#include <set>
using namespace std;
bool is_isomorphic(string input1, string input2)
{
if(input1.length()!= input2.length())
return false;
set<char> usedLetters;
map<char, char> transformations;
for(int i = 0 ; i < input1.length(); i++) {
auto iter = transformations.find(input1[i]);
if (iter != transformations.end()) {
if (iter->second == input2[i]) continue;
else return false;
}
if (usedLetters.count(input2[i])) return false;
usedLetters.insert(input2[i]);
transformations[input1[i]] = input2[i];
}
return true;
}
int main() {
cout<<is_isomorphic("abcd", "aabb");
return 0;
}
You need 2 arrays, one to know which character of input2 correspond to a given character of input1, and a second to check if a character of input2 is not already affected to a character of input1.
#include <iostream>
#include <string>
using namespace std;
bool is_isomorphic(const string& input1, const string& input2)
{
if (input1.length() != input2.length()) {
return false;
}
char map[256]{};
bool used[256]{};
for (size_t i = 0; i < input1.length(); i++) {
unsigned char val1 = input1[i];
if (!map[val1]) {
unsigned char val2 = input2[i];
if (used[val2]) {
return false;
}
map[val1] = input2[i];
used[val2] = true;
} else
if (map[val1] != input2[i]) {
return false;
}
}
return true;
}
int main() {
cout << is_isomorphic("abcd", "aabb") << endl;
cout << is_isomorphic("abcdb", "zerte") << endl;
return 0;
}

C++ Creating Lottery Guessing Program

Okay so the project is to create a lottery number composed of 10 random positive integers and the user is suppose to guess it until the user guesses the correct number. All of my code looks good but when I run the program and enter in a number it gives me this MSVS Runtime Library error? I dont even know what it means as I am fairly new to programming. Help would be very appreciated!
Main.cpp
#include <iostream>
#include <cmath>
#include <ctime>
#include "Lottery.h"
using namespace std;
int main() {
const int size = 9; //declare variables
int win[size];
int g;
srand(time(NULL));
assign(win, size);
draw(win, size);
g = entry();
if (check(win,size,g) == true) {
cout << "Congradulations! You have won the lottery!" << endl;
}
else {
cout << "Try again!" << endl;
}
printOut(g);
}
Lottery.cpp
#include <iostream>
#include <cmath>
#include "Lottery.h"
using namespace std;
int entry() {
int guess;
cout << "Enter a number from 0 to 99." << endl;
cin >> guess;
return guess;
}
void assign(int w[], int s) {
for (int i = 0; i < s; i++) {
w[s] = -1;
}
}
bool check(int w[], int s, int g) {
for (int i = 0; i < s; i++) {
if (g == w[i]) {
return true;
}
}
return false;
}
void draw(int w[], int s) {
for (int i = 0; i < s; i++) {
int tmp = rand() % 100;
if (check(w, s, tmp)) {
i--;
}
else
w[i] = tmp;
}
}
void printOut(int g) {
cout << "Numbers you have chosen:" << " " << g << endl;
}
Lottery.h
#ifndef LOTTERY_INCLUDED
#define LOTTERY_INCLUDED
void assign(int[], int);
bool check(int[], int, int);
void draw(int[], int);
int entry();
void printOut(int);
#endif //LOTTERY
Debugging tutorials are available elsewhere. But if something bad happens, don't panic and look for instructions.
First, your runtime error:
This has a link "Break and open exception settings" link or a "Break" button. Break which will take you to the end of main if you click it.
The details say we did something bad near win.
Look at this:
void assign(int w[], int s) {
for (int i = 0; i < s; i++) {
w[s] = -1; //<------Oh oops!
}
}
We know the length of the array is s i.e. 9, and are using w[s] where we clearly meant w[i].
The extra details in the error are telling you a possible place to look.

assistance in sorting an array of pointers pointing to a string array in c++

I have been attempting to find a way to sort an array of pointers (pointing to strings) and then display the non-sorted list and the sorted list but no mater what I try the 2nd printed list is always identical to the original non-sorted list. Any help you could offer would be greatly appreciated (and I'm sorry if my code is a mess I'm a new student)
this is my main(lab5.cpp)
#include <cstdlib>
#include <iostream>
#include "student.h"
#include <string>
using namespace std;
int main(int argc, char *argv[])
{
student stu;
stu.list();
system("PAUSE");
return EXIT_SUCCESS;
}
This is my header(student.h)
#include <string>
class student
{
public:
student( );
void setnameage();
int getage(int);
std::string getname(int);
void sort();
void list();
private:
std::string name[50];
std::string nameL[50];
int age[50];
std::string * Pname ;
int * Page;
int amount;
};
This is my object (student.cpp)
#include <iostream>
#include <iomanip>
#include "student.h"
#include <string>
using namespace std;
//constructor
student::student()
{
int i = 0;
amount = 0;
Pname = name;
Page = age;
while (i != 50)
{
age[i] = 0;
name[i] = "A";
i = i +1 ;
}
std::cout << "Enter number of students(max 50) \n" << ">";
std::cin >> amount;
}
//sets the neame and the age
void student::setnameage()
{
int i = 0;
while (i != amount)
{
std::cout << "Enter name " << i+1 <<" (last, first):";
std::cin >> name[i] >> nameL[i];
std::cout << "enter age";
std::cin >> age[i];
i++;
}
}
//get age
int student::getage(int i)
{
return age[i];
}
//get name
std::string student::getname(int i)
{
return name[i];
}
//sorts the aray of pointers
void student::sort()
{
std::string tempL;
int tempN;
i = 0
for (int i = 1; i <= amount-1; i++)
{
for(int j=i+1; j <= amount; j++)
{
if(Pname[i].compare(Pname[j]) > 0)
{
tempN = Page[i];
Page[i] = Page[j];
Page[j] = tempN;
// tempL = Pname[i];
Pname[i].swap(Pname[j]);
//Pname[j] = tempL;
}
}
}
}
//displayes the final results
void student::list()
{
setnameage();
int i = 0;
std::cout << "original list\n-------------";
while(i != amount)
{
std::cout<< "\n" << getname(i) << ">" << getage(i);
i++;
}
sort();
i = 0;
std::cout << "\nAlphabetized list\n-------------";
while(i != amount)
{
std::cout<< "\n" << Pname[i] << ">" << Page[i];
i++;
}
}
First let me say your program has a lot of design problems, but to answer your actual question:
The trouble is you don't have an array of 50 pointers, you just have one pointer to the start of the array. In your sort function you have this line to swap the string pointers:
Pname[i].swap(Pname[j]);
But this doesn't swap the pointers, it swaps the original strings. So instead of ending up with the original array of strings, and a re-ordered array pointing to those strings, you just end up with an array of re-ordered strings.
You should change std::string* pName; to std::string* pName[50];. At the start of your program, initialise the array to point to the strings.
for (int i = 0; i < 50; i++) pName[i] = &name[i];
Then in your sort function you should use std::swap() to swap the pointers themselves:
std::swap(pName[i], pName[j]);
Finally, since pName[i] is now a pointer, whenever you actually want to access the string you have to dereference the pointer. For example,
if(Pname[i].compare(Pname[j]) > 0)
becomes
if(Pname[i]->compare(*Pname[j]) > 0)
The same problem exists with your method of sorting the ages.
A much better design for your program would be to use std::list<std::pair<std::string, int>> to store the names and ages. Then you can use the built in sorting functions to sort the list (and easily make a copy of it if you need to keep the original as well).