use array to change every digit in a 3-digit number - c++

#include<iostream>
using namespace std;
int main(){
int n,d1,d2,d3;
cout<<"Enter a 3-digit positive integer"<<endl;
cin>>n;
d1=n/100;
d2=n%100/10;
d3=n%10;
int a[3]{d1,d2,d3};
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
}
This code takes a 3-digit integer as input and returns a new number in which all non-zero digits in the original are replaced by the distance between the digit and 10, for example, if one of the digits is 2 so the new digit will be 10-2=8. But the problem is with the output.
I want the program to print (The new number is :(here the new digits in the same line)), instead of repeating the message and printing each digit in a separate line. How can I do that??
Thanks in advance.

This for loop,
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
cout<<"The new number is :"<<a[i]<<endl;
}
Is the issue for your problem. This means that your printing The new number is : on every iteration. What we need to do is, print it once and print all the integers after it. Its very simple, just change the position of the std::cout to be before the for loop and we can put in a little optimization; we dont need to store the 10 - a[i], we can directly print it.
cout << "The new number is : ";
for (int i = 0; i < 3; ++i) {
if(a[i] != 0) {
std::cout << (10 - a[i]);
}
}
Bonus: Try not to use using namespace std; as its a bad practice. Basically what it does is, it takes the whole std namespace and dumps it into the global namespace. If its for competitive programming and time is limited, then it would be okay but for general programming, avoid it.

u can print the information out from the for loop or u can do for loop like this
for (int i = 0; i < 3; ++i) {
if(a[i]!=0){
a[i]=10-a[i];
}
if(i == 0)
cout<<"The new number is :";
cout <<a[i];
}
cout << endl

Related

Finding if a string is contained in another string without "find" in c++

I wrote this program to find if a string is contained in another string (see paragraph below this, I tried to explain what I want it to do). When I test it, sometimes it works, most of the times it gives me the error "String subscript out of range". I'm very new to C++, I'd appreciate someone to tell me how can I improve this code or why I'm being dumb, because I really don't get why it doesn't work.
what i want this to do is find if string one can be found in string way;
so i want it to check for every letter of string way if the letter [i] is equal to the first letter of the string one (way[i+0]==one[0]),
and way[i+1]==one[1] and so on for all letters in one.
so for example way = abankjve and one = ank
it takes the first letter in way (a) and gets the first letter in one(a). the're equal. but we see that way[0+1] is not equal to one[1]. so o can't be true.
it goes on like this till it gets to way[2]=a. way[2+0]=one[0]. o is true. then it checks way[2+1]=one[1]. true! then it checks way[2+2]=one[2]. true! then
one is contained in way.
#include <iostream>
using namespace std;
int main()
{
string way, one;
bool o=false;
cin >> way;
cin >> one;
for (int i = 0; i < way.size(); i++)
{
for (int k = 0; k < one.size(); k++)
{
if (way[i + k]==one[k])
{
o = true;
}
}
}
cout << o << endl;
}
If you think about it, way[i+k] will result in index out of range.
say way is length of 5 and one is length of 3.
i+k's range is 0 <= i + k <= 6. Witch is bigger than the possible index of way.
change first for loop for (int i = 0; i < way.size(); i++) to
for (int i = 0; i <= (int)way.size() - one.size(); i++)
Note I've used static_cast to int. *.size() returns unsigned int so if one's size is bigger than way's size, the result won't be what you've imagined.
#include <iostream>
#include <string>
int main()
{
std::string way, one;
std::cin >> way;
std::cin >> one;
bool found{};
for (size_t i = 0; i < way.size() - one.size()+1; i++)
{
if(one == way.substr(i, one.size())) {
found = true;
break;
}
}
std::cout << found;
}
Demo

Issues with checking an array moving both forwards and backwards simultaneously and issue printing values stored in a pointer array

Preface: Currently reteaching myself C++ so please excuse some of my ignorance.
The challenge I was given was to write a program to search through a static array with a function and return the indices of the number you were searching for. This only required 1 function and minimal effort so I decided to make it more "complicated" to practice more of the things I have learned thus far. I succeeded for the most part, but I'm having issues with my if statements within my for loop. I want them to check 2 separate spots within the array passed to it, but it is checking the same indices for both of them. I also cannot seem to get the indices as an output. I can get the correct number of memory locations, but not the correct values. My code is somewhat cluttered and I understand there are more efficient ways to do this. I would love to be shown these ways as well, but I would also like to understand where my error is and how to fix it. Also, I know 5 won't always be present within the array since I'm using a pseudo random number generator.
Thank you in advance.
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// This is supposed to walk throught the array both backwards and forwards checking for the value entered and
// incrementing the count so you know the size of the array you need to create in the next function.
int test(int A[], int size, int number) {
int count = 0;
for (int i = 0; i <= size; i++, size--)
{
if (A[i] == number)
count++;
// Does not walk backwards through the array. Why?
if (A[size] == number)
count++;
}
cout << "Count is: " << count << endl;
return (count);
}
// This is a linear search that creates a pointer array from the previous "count" variable in function test.
// It should store the indices of the value you are searching for in this newly created array.
int * search(int A[], int size, int number, int arr_size){
int *p = new int[arr_size];
int count =0;
for(int i = 0; i < size; i++){
if(A[i]==number) {
p[count] = i;
}
count++;
}
return p;
}
int main(){
// Initializing the array to zero just to be safe
int arr[99]={0},x;
srand(time(0));
// Populating the array with random numbers in between 1-100
for (int i = 0; i < 100; i++)
arr[i]= (rand()%100 + 1);
// Was using this to check if the variable was actually in the array.
// for(int x : arr)
// cout << x << " ";
// Selecting the number you wish to search for.
// cout << "Enter the number you wish to search for between 1 and 100: ";
// cin >> x;
// Just using 5 as a test case.
x = 5;
// This returns the number of instances it finds the number you're looking for
int count = test(arr, (sizeof(arr)/4), x);
// If your count returns 0 that means the number wasn't found so no need to continue.
if(count == 0){
cout << "Your number was not found " << endl;
return 0;
}
// This should return the address array created in the function "search"
int *index = search(arr, (sizeof(arr)/4), x, count);
// This should increment through the array which address you assigned to index.
for(int i=0; i < count; i++) {
// I can get the correct number of addresses based on count, just not the indices themselves.
cout << &index[i] << " " << endl;
}
return 0;
}
I deeply appreciate your help and patience as well as I want to thank you again for your help.

Did a competitive-like problem right but need help on improving its efficiency

The problem is simple. I'm given N - the number of digits in a number and then N digits of a number. I need to do exactly one digit-switch and get the highest number possible. I did do the problem right (as in gives out the right number) but it will be hitting the 1 second time restriction afaik. How do I improve on the efficiency of my program so it would go under the 1 second time restriction with N <= 10^6. New on Stack overflow so tell me if I did something wrong
with asking the question so I can fix it. Thanks. Here's my solution:
main:
int n;
cin >> n;
int a[n+1];
for(int i=0;i<n;++i)
cin >> a[i];
int maxofarray1;
bool changeHappened=false;
bool thereAreTwoSame=false;
for(int i=0;i<n;++i) //changing the two digits to make the highest number if possible
{
maxofarray1=maxofarray(a,i+1,n);
if(a[i]<maxofarray1)
{
int temp=a[a[n]];
a[a[n]]=a[i];
a[i]=temp;
changeHappened = true;
break;
}
}
for(int i=0;i<n;++i) //need to check if there are two of the same digit so I can change
//those two making the number the same instead of making it lower
for(int j=i+1;j<n;++j)
if(a[i]==a[j])
{
thereAreTwoSame=true;
break;
}
if(!changeHappened) //if the change has not been yet made, either leaving the number as is
//(changing two same numbers) or changing the last two to do as little "damage" to the number
{
if(!thereAreTwoSame)
{
int temp=a[n-1];
a[n-1]=a[n-2];
a[n-2]=temp;
}
}
for(int i=0;i<n;++i)
cout << a[i] << " ";
return 0;
maxofarray:
int maxofarray(int a[], int i,int n) //finding the maximum of the array from i to n
{
int max1=0;
int maxind;
for(int j=i;j<n;++j)
{
if(max1<a[j])
{
max1=a[j];
maxind=j;
}
}
a[n]=maxind; //can't return both the index and maximum (without complicating with structs)
//so I add it as the last element
return max1;
}
The problem in your code is complexity. I didn't fully understand your algorithm, but having nested loops is a red flag. Instead of trying to improve bits and pieces of your code you should rather rethink your overall strategy.
Lets start by assuming the digit 9 does appear in the number. Consider the number is
9...9 c ...9...
where 9...9 are the leading digits that are all 9 (possibly there are none of them). We cannot make the number bigger by swapping one of those.
c is the first digits !=9, ie its the place where we can put a 9 to get a bigger number. 9 is the digit that will make the number maximum when put in this place.
Last, ...9... denotes the last appearance of the digit 9 and digits sourrinding that. After that 9 no other 9 appears. While we increase the number by replacing c, the number will get smaller be replacing that 9, hence we have to choose the very last one.
For the general case only a tiny step more is needed. Here is a rough sketch:
std::array<size_t,10> first_non_appearance;
std::array<size_t,10> last_appearance;
size_t n;
std::cin >> n;
std::vector<int> number(n);
for (size_t i=0;i <n;++i) {
std::cin >> a[i];
for (int d=0;d<10;++d) {
// keep track of first and last appearance of each digit
}
}
size_t first = 0;
size_t second = 0;
for (int d=0;d<10;++d) {
// determine biggest digit that appeared and use that
}
std:swap( a[first],a[last] );
It is not complete, perhaps requires handling of special cases (eg number with only one digit), but I hope it helps.
PS: You are using a variable length array (int a[n+1];), this is not standard C++. In C++ you should rather use a std::vector when you know the size only at runtime (and a std::array when the size is known).
VLA (variable length arrays) are not standard. So instead of using this nonstandard feature, you might want to use a STL data type.
Given N is rather big, you also avoid stack overflow, given that VLA are allocated on the stack. And STL containers with variable length allocate on the heap.
Then, as you pointed out yourself, it makes sense to remember the index of the last occurrence of each digit, avoiding to search over and over again for a swap candidate index.
Your implementation idea is basically, to replace the first digit from the left, which has a bigger replacement to the right of it.
This is how I did it:
static void BigSwap(std::string& digits)
{
int64_t fromRight[10];
size_t ndigitsFound = 0;
for (size_t i = 0; i < 10; i++)
fromRight[i] = -1;
size_t i = digits.size() - 1;
while (ndigitsFound < 10 && i > 0)
{
if (-1 == fromRight[digits[i] - '0'])
{
fromRight[digits[i] - '0'] = static_cast<int64_t>(i);
ndigitsFound++;
}
i--;
}
for (size_t j = 0; j < digits.size(); j++)
{
char d = digits[j] - '0';
for (char k = 9; k > d; k--)
{
if (fromRight[k] != -1 && static_cast<size_t>(fromRight[k]) > j)
{
auto temp = digits[j];
digits[j] = k + '0';
digits[fromRight[k]] = temp;
return;
}
}
}
}

Prime number finder cannot find prime, stops after 7

So I made a simple prime number finder for the numbers between 3 and 200. It has to use a boolean variable, just fyi. No errors occur. output is:
The prime numbers between 3 and 200 are:
3
5
7
Why does it not keep going? I have drawn it out on paper time and again and cannot find my logic error.
In addition; I wrote this out by hand because I do not know how to get the contents of my file. It exists on a remote host which I do not have root access to. Is there a better way to copy the file?
#include <iostream>
using namespace std;
int main()
{
int count=0;
cout<<"The prime numbers between 3 and 200 are: "<<endl;
for (int i=3;i<=200;i++)
{
for (int j=2;j<i;j++)
{
bool ptest=i%j;
if (!ptest)
{
break;
}
else if (ptest)
{
count=count+1;
if (count==(i-2))
cout<<i<<endl;
}
}
}
}
You forgot to set count back to 0 after using it in the j loop. Move the line:
int count = 0;
to be inside the first for loop. Then your program works correctly (although as msw indicated, it is not the most efficient technique!)
Some things to consider:
You don't need to consider any even numbers in your code.
You have some logic errors in your code. The value of count needs to be checked after the second for loop. count needs to be reset before the second for loop begins.
You can stop immediately after you find the number is not prime in the inner loop instead of continuing on. You can just use a flag isPrime instead of counting.
Here's a version of the code that works for me:
#include <iostream>
using namespace std;
int main()
{
cout << "The prime numbers between 3 and 200 are: " <<endl;
for (int i=3; i <= 200; i += 2) {
bool isPrime = true;
for (int j=3; j < i; j += 2) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime)
{
cout << i << endl;
}
}
}
You don't have to loop till j reach i, instead you can check if j < sqrt(i) ,i.e. write in the second for loop: for (int j=3; j*j<=i; j+=2)

Can't figure out why this output formatting loop is going infinite

My program is supposed to take in a number from user input, determine whether or not it is prime, and then if it is not, output the factors of the entered number, 5 to a line. The 5 to the line part is where everything goes haywire, the loop i wrote should work fine as far as i can tell, however no matter how much i change it around, it does one of two things, 1) goes infinite with either new lines or the first factor, or 2) outputs a line with 5 of each factor. Here's the code:
else
{
cout << "\nNumber is not prime, it's factors are:\n";
for (int x = 2; x < num; x++)
{
factor=num%x;
if (factor==0)
{
int t=0;
cout << x << "\t";
t++;
for (int t; t <= 5; t++) // THE TROUBLE LOOP
{
if(t>=5)
{
t=0;
cout << endl;
}
}
}
}
}
Replace the declaration of t in the loop since you've declared t prior to the loop:
for(; t <= 5; t++)
With int t in the loop declaration you are overriding t as an uninitialized variable that will have a garbage value.
Outside of this problem your loop is infinite since you will be resetting t to 0 whenever it equals 5.
In the for loop change the
int t
to
t=0
it is the
for(int t,t<=5,t++)
the int t part in particular that is causing the issue.
#GGW
Or this:
int t = 0;
//some code
for(t; t <= 5; t++)
//more code