Problem Statement: We have to input a vector and then there is a certain number of queries. For one particular query, we have to search for that number in the vector. If found we print."Yes " and if not found we print the next greater number to the query and print "No ".
The vector is sorted.
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int size,q,nq=0;
cin>>size;
vector<int> vec1;
int element;
for (int i = 0; i < size; i++)
{
cin>>element;
vec1.push_back(element);
}
cin>>q;
for(int j=0;j<q;j++)
{
cin>>nq;
for(int k=0;k<vec1.size();k++)
{
if(vec1[k]==nq)
{
cout<<"Yes "<<k+1<<endl;
break;
}
else if(vec1[k]>nq)
{
cout<<"No "<<k+1<<endl;
break;
}
}
}
return 0;
}
The code runs perfectly but for some test cases, there is an error due to time.
I need to improve this code. I am struggling with this as I have just learned about std::vector.
as this problem related to sorted vector it requires use Binary Search.
Binary search allows to answer queries with O(Log(N)) vs O(N) complexity (https://en.wikipedia.org/wiki/Computational_complexity). So this is why your implementation is too slow for this problem.
Here is manual implementation Using Binary Search with Vectors.
And also it is more clear to use std::lower_bound function. It does exact the thing needed:
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int size,q,nq=0;
cin>>size;
vector<int> vec1;
int element;
for (int i = 0; i < size; i++)
{
cin>>element;
vec1.push_back(element);
}
cin>>q;
vector<int>::iterator qit;
for(int j=0;j<q;j++)
{
cin>>nq;
qit = std::lower_bound(vec1.begin(), vec1.end(), nq);
if(qit != vec1.end())
{
if(*qit == nq)
cout << "Yes " << (qit - vec1.begin());
else cout << "No " << *qit << " " << (qit - vec1.begin());
}
else cout << "No " << (qit - vec1.begin());
}
return 0;
}
Related
I need to take 200 randomizes numbers from a file, separate them into even and odd, and make them show up from lowest to highest in their even or odd parts.
I got the code for making it into even and odd from here but the original way had 10 instead of 200 and made the user input the numbers.
I reworked it into this but I get a repeat of the same number then an error that reads Exception thrown: write access violation with a mark near the odd[oddcnt++] = arr[i];
My code so far
#include <iostream>
#include <fstream>
using namespace std;
class Random
{
private:
int x, arr[200], even[200], odd[200], evncnt = 0, oddcnt = 0, i;
public:
void readFile();
};
void Random::readFile()
{
fstream File("Random.txt");
if (File.is_open())
{
while(File >> x)
{
for (i = 0; i < 200; i++)
{
arr[i] = x;
}
for (i = 0; i < 200; i++)
{
if (arr[i] % 2 == 0)
{
even[evncnt++] = arr[i];
}
else
{
odd[oddcnt++] = arr[i];
}
}
cout << "\n The even numbers are: ";
for (i = 0; i < evncnt; i++)
{
cout << even[i] << "";
}
cout << "\n The odd numbers are: ";
for (i = 0; i < oddcnt; i++)
{
cout << odd[i] << "";
}
}
File.close();
}
}
int main()
{
Random file;
file.readFile();
system("pause");
return 0;
}
Your loops are all wrong. This is how it should look
i = 0;
while (file >> x)
{
arr[i] = x;
i++;
}
for (i = 0; i < 200; i++)
{
if (arr[i]%2==0)
...
}
If you put one loop inside another (like you did) then the inner loop executes fully every time the outer loop executes once. That's not what you want (in this case).
The answer is given already by John. So everything OK.
Additionally, I would like to show you the power of modern C++. Especially with using algorithms. You can write very elegant solutions.
Thers is no loop and only vey few variables.
You will of course not copy and paste it, because you will not understand it fully. But it should give you an idea how such a problem could be analysed, then designed, and then coded.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <string>
class Random {
std::vector<int> values{};
public:
void readFile(const std::string& fileName);
void printOdds();
void printEvens();
};
void Random::readFile(const std::string& fileName) {
// Open file and check, if it could be opened
if (std::ifstream inputFileStream(fileName); inputFileStream) {
// Clear old content in our class
values.clear();
// Copy the contents from the vile into our vector
std::copy(std::istream_iterator<int>(inputFileStream), {}, std::back_inserter(values));
// sort the values
std::sort(values.begin(), values.end());
}
else { // File could not be opened
std::cerr << "\n*** Error: File could not be opened: " << fileName << "\n\n";
}
}
// Copy all odd values to std::cout
void Random::printOdds() {
std::copy_if(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "), [](const int i) { return (i % 2) != 0; });
std::cout << "\n\n";
}
// Copy all even values to std::cout
void Random::printEvens() {
std::copy_if(values.begin(), values.end(), std::ostream_iterator<int>(std::cout, " "), [](const int i) { return (i % 2) == 0; });
std::cout << "\n\n";
}
// Driver code
int main() {
Random r;
r.readFile("r:\\random.txt");
r.printEvens();
r.printOdds();
return 0;
}
i'm studying C++ for C programmers course (coursera) and in module 4 there is an example for how to use istream iterators to load data to STL vector ..but when i tried the code it only printed the first number from the file. i can't find the mistake in the code.
note :the instructor didn't run the code, he Taught is using PDF. so maybe there something missing in it.
#include <iostream>
#include <fstream>
#include <iterator>
#include <vector>
using namespace std;
int main()
{
fstream data_file("data.txt");
istream_iterator<int> start_file(data_file), end_file;
vector<int> data(start_file, end_file);
int sum = 0;
for (auto i = start_file; i != end_file; i++)
{
sum += *i;
cout << *i << endl;
}
cout << data.size()<<endl;
cout << sum << endl;
cout << (sum* 1.0) / data.size() << endl;
return 0;
}
I'm getting a strange error when trying to iterate a Map of Vectors. I'm using the Stanford CS106B class libraries for this project and when I try to compile the code I get an error telling me that "itr has no member named 'first' "
I have tried searching for solutions to this problem and I have found many similar entries but the answers seem to mimic what I'm doing. I'm sure I'm missing something simple...
#include <iostream>
#include <fstream>
#include <string>
#include "console.h"
#include "simpio.h" // for getLine
#include "strlib.h"
#include "vector.h"
#include "queue.h"
#include "map.h"
#include <iterator>
using namespace std;
void CountLetters(ifstream &filename) {
int index=0;
Vector<int> counts;
for (int i=0; i<=26; i++) {
counts.add(0);
}
char c;
while (!filename.eof()) {
c=filename.get();
index=c-'a';
if (index>=0 && index<26) {
c=stringToChar(toLowerCase(charToString(c)));
counts[index]++;
}
}
for (int y=0; y<=26; y++) {
cout << char('a'+y) << ": " << counts[y] << endl;
}
filename.close();
}
Map <string, Vector<char> > assembleSets (ifstream &in, int seed) {
Map <string, Vector<char> > letterSets;
char c;
Vector<char> workingText;
string letterSet;
while(!in.eof()) {
if (workingText.size()<seed) { // Build the intial set of "seed" letters.
c=in.get();
workingText.add(c);
}
else {
c=in.get();
letterSet.clear();
for (int i=0; i<workingText.size()-1; i++) {
letterSet+=workingText[i]; // add the letter to the letter set.
workingText[i]=workingText[i+1]; // move the letter down one in the vector (simulate queue).
}
letterSet+=workingText[seed-1];
workingText[seed-1]=c; // add the newwest letter to the workingText but do not add it to the letter set.
// Check to see if the letter set exists already, if not, add it.
if (!letterSets.containsKey(letterSet)) {
Vector<char> blank;
letterSets.add(letterSet,blank);
letterSets[letterSet].add(c);
}
else {
// Add the next character to the vector of characters for that letter set.
letterSets[letterSet].add(c);
}
}
}
return letterSets;
}
int main() {
ifstream in;
int mSeed =0;
while (true) {
string fileName = getLine("Please enter a file name");
in.open(fileName);
if(in.fail()) cout << "Couldn't open file!" << endl;
else break;
}
// CountLetters(in);
while (true) {
mSeed=getInteger("Enter a seed value: ");
if (mSeed>0&&mSeed<=10) {
break;
} else {
cout << "Please choose a value from 1 to 10." << endl;
}
}
Map<string, Vector<char> > letterSets = assembleSets(in, mSeed);
Map<string, Vector<char> > :: iterator itr;
for (auto& it: letterSets) {
string keys = (it.first);
Vector<char> values = it.second;
}
return 0;
}
Any help would be fantastic! I'm really scratching my head.
It simply means that Map<string, Vector<char> > :: iterator.
Using std::map instead of Map and std::vector instead of Vector compiles correctly.
Check the implementation of your custom iterator.
Anyway i suggest you using the range-based syntax for this (if you use the C++ standard library):
for (auto& it : letterSets)
{
string key = it.first;
vector<char> values = it.second;
}
Here is the code. I have used a self calling function to create a nested loop of exact size(that is determined by the length of word entered by user) neccessary.
I took me about 5hrs to write it and debug it. Have I over did it? Are there any other simpler ways to do it without using any specifically designed c++ library functions?
//PROGRAM TO PRINT ALL PERMUTAIONS OF LETTERS OF A WORD
#include<iostream>
#include<string.h>
#include<stdio.h>
using namespace std;
char a[11],p[11]; //a to store the word entered
int flag; //p to store a permutaion untill it is printed
void permute(int* chk,int n ,int pos)
{ int i,j,k;
int nxtchk[10];
flag=1;
for(i=0; i<n ; i++ )
{ for(j=0;j<n;j++)
nxtchk[j]=1;
if(chk[i])
{
p[pos]=a[i];
chk[i]=0;
for(j=0;j<=pos;j++)
for(k=0;k<n;k++)
if(p[j]==a[k])
nxtchk[k]=0;
if(pos+1<n)
permute(nxtchk,n,pos+1);
}
}
if(flag) //flag used to ensure each permutation is printed once only
{ cout<<p<<" "; flag=0; }
}
int main()
{
int chk[10]={1,1,1,1,1,1,1,1,1,1};
cout<<"Enter a word whose letters are all different: "; gets(a);
int n=strlen(a);
p[n]='\0';
permute(chk,n,0);
}
You can look at std::next_permutation:
// next_permutation example
#include <iostream> // std::cout
#include <algorithm> // std::next_permutation, std::sort
int main() {
int myints[] = { 1,2,3 };
std::sort(myints, myints + 3);
std::cout << "The 3! possible permutations with 3 elements:\n";
do {
std::cout << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
} while (std::next_permutation(myints, myints + 3));
std::cout << "After loop: " << myints[0] << ' ' << myints[1] << ' ' << myints[2] << '\n';
return 0;
}
You may also want to browse this article: C++ Algorithms: next_permutation().
It is a variant of permutation without any specifically designed library functions (except std::swap but this can be easily substituted by code)
#include <iostream>
#include <vector>
#include <list>
#include <iterator>
void permute(std::vector<int> a, int i, int n)
{
int j;
if (i == n) {
std::copy(std::begin(a), std::end(a), std::ostream_iterator<int>(std::cout, " "));
std::cout<<'\n';
}
else
{
for (j = i; j <= n; j++)
{
std::swap(a[i], a[j]);
permute(a, i+1, n);
std::swap(a[i], a[j]);
}
}
}
int main()
{
std::vector<int> v = { 5,7,3,8 };
permute(v, 0, v.size() -1 );
return 1;
}
also possible to use prev_permutation
a. Store 5 names in a list. Allow the user to input each name.
b. Sort the list alphabetically in ascending order and print the list.
c. Sort the list alphabetically in descending order and print the list.
d. Ensure your code can be executed without bugs or errors.
im stuck in sorting the list in descending order please help:(
below is my source code of the ascending order.
#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;
}
To sort a list, you don't need std::set, you can store the names in a std::vector and then use the function std::sort from the header algorithm. There is also a version of the function that takes a predicate and thus you can reverse the order using this predicate, specifying reverse comparison. Have a look at the documentation of sort. Also have a look at greater that is defined in the header functional - this is a predicate you can use to reverse the sorting order. Have a look at this short example on ideone:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <functional>
using namespace std;
int main() {
vector<string> test;
test.push_back("a");
test.push_back("c");
test.push_back("b");
sort(test.begin(), test.end());
for (unsigned i = 0; i < test.size(); ++i) {
cout << test[i] << endl;
}
sort(test.begin(), test.end(), greater<string>());
for (unsigned i = 0; i < test.size(); ++i) {
cout << test[i] << endl;
}
return 0;
}
To display the set in reverse order, you may use:
std::for_each(sortedItems.rbegin(), sortedItems.rend(), &print);