Square Root Code C++ without sqrt() - c++

I have to create a code where the user inputs a number which is a perfect square, and I have to show its root. I've made this code, but I'm getting Segmentation Fault 11 , in this piece: int j = squareRootVector[i];
squareRoot.push_back(j);.
I can't change the code too much, so is there a way that I can do that?
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout <<
"Enter the number:\n";
int input;
int number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
cin >> number;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
cout << number << endl;
squareRootVector.push_back(divider);
}
}
for(int i = 0; i < squareRootVector.size(); i++) {
cout << squareRootVector[i] << " ";
/*******PROBLEM*******/
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
/*********************/
}
int root;
for (int i = 0; squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is: " << root << endl;
return 0;
}

The behaviour on accessing squareRootVector[i+1] with i just one below size (which your loop constaint allows) is undefined.
Consider writing
for (std::size_t i = 1; i < squareRootVector.size(); i++) {
instead, and rebasing the for loop body accordingly. I've also slipped in a change of type for i.

Shortly, the problem is that the last cycle in the last "for":
for(int i = 0; i < squareRootVector.size(); i++)
has the following line in it:
squareRootVector[i] == squareRootVector[i+1];
This is an "out of limits" error: squareRootVector only has squareRootVector.size() elements (let's say n), and the elements are indexed from 0 to n-1.
squareRootVector[i+1] in the last cycle points one element after the last one of squareRootVector, which is undefined behavior.

Using vector::iterator is proper way.
for(vector<int>::iterator it = squareRootVector.begin(); it != squareRootVector.end(); ++it)
{
if( (it+1) == squareRootVector.end() )
{
//what to do if there's no next member???
break;
}
if( *it == *(it+1) )
{
squareRoot.push_back(*it);
}
}

Thanks for the answers, guys. I've ended up with this code:
#include <iostream>
#include <vector>
using namespace std;
int main() {
cout << "Enter the number:\n";
int input = 0;
int number = 0;
cin >> input;
number = input;
int divider = 2;
vector<int> squareRootVector;
vector<int> squareRoot;
for(int divider = 2; number > 1; divider++) {
while((number % divider) == 0) {
number /= divider;
squareRootVector.push_back(divider);
}
}
int vectorSize = squareRootVector.size() - 1;
for(int i = 0; i < vectorSize; i++) {
if(squareRootVector[i] == squareRootVector[i+1]) {
int j = squareRootVector[i];
squareRoot.push_back(j);
}
}
int root = 1;
for (int i = 0; i < squareRoot.size(); i++) {
root = root * squareRoot[i];
}
cout << "Square Root of " << input << " is " << root << endl;
return 0;
}

Related

Why am I not able to push a pair after a limit in the vector?

The problem is to find if a given sequence of numbers can form a valid permutation or not. The problem statement is trivial for the real problem. So, I am pushing a pair of integers into the vector. The first part being the number itself and second being 0 or 1.
The code works fine till a sequence 1041 long (specific after debugging a lot). Just to debug I added a print statement after pushing each pair inside the vector. For a length of 1042, the code shows pushed 1040 and then pushed 1 (which is weird) and then just hangs on there.
I am attaching the code as well as the input and terminal output.
You can just check the main function
Code
#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
using namespace std;
bool comparator_function(pair<int, int> a, pair<int, int> b) {
return (a.first < b.first);
}
//index_added -> the index at which the latest element was added
void set_r_array(int* r_array_ref, int* per_array_ref, int size, int* count, int index_added) {
for(int i = 1;i <= size; i++) {
count[i] = 0;
}
int temp = index_added;
while(index_added <= size) {
if(index_added == size) {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = size;
break;
}
else {
r_array_ref[temp] = -1;
break;
}
}
else {
if(per_array_ref[index_added] == 0) {
r_array_ref[temp] = index_added;
break;
}
else {
index_added++;
}
}
}
for(int i = 1;i <= size; i++) {
if(r_array_ref[i] != -1) {
count[r_array_ref[i]]++;
}
}
}
bool check_max(int* count, int next_element, int size) {
int max_count = -1, index = 0;
for(int i = 1;i <= size; i++) {
int temp_val = count[i];
if(max_count <= temp_val) {
max_count = temp_val;
index = i;
}
}
int num = 0;
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
num++;
}
}
//one max
if(num == 1) {
if(next_element == index) {
return true;
}
return false;
}
else {
for(int i = 1;i <= size; i++) {
if(count[i] == max_count) {
if(next_element == i) {
return true;
}
}
}
return false;
}
}
int main() {
int testCases;
cin >> testCases;
cin.ignore();
while(testCases-- > 0) {
int n, result_flag = 0;
cin >> n;
cin.ignore();
vector<pair<int, int>> per;
int temp;
for(int i = 0;i < n; i++) {
cin >> temp;
pair<int, int> temp_pair = make_pair(temp, i+1);
per.push_back(temp_pair);
//debug statement
cout << "pushed " << temp << endl;
}
auto start = std::chrono::high_resolution_clock::now();
cout << "start" << endl;
sort(per.begin(), per.end(), comparator_function);
int permutation_array[n+1], r_array[n+1], count[n+1];
for(int i = 0;i <= n; i++) {
permutation_array[i] = 0;
r_array[i] = i;
count[i] = 1;
}
cout << "end" << endl;
permutation_array[per[0].second] = per[0].first;
set_r_array(r_array, permutation_array, n, count, per[0].second);
//insertion of numbers
for(int i = 1;i < n; i++) {
//check if the next element inserted has the largest count rn or not
int next_element = per[i].second;
if(!check_max(count, next_element, n)) {
cout << "No" << endl;
result_flag = -1;
break;
}
permutation_array[per[i].second] = per[i].first;
set_r_array(r_array, permutation_array, n, count, per[i].second);
}
if(result_flag == 0) {
cout << "Yes" << endl;
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(stop - start);
cout << "Time: " << duration.count() << " microseconds" << endl;
}
}
Input 1
1
5
2 3 4 5 1
Output 1
pushed 2
pushed 3
pushed 4
pushed 5
pushed 1
start
end
Yes
Input 2
1
1042
1 2 3 4 ... so on till 1042
Output 2
pushed 1
pushed 2
.
.
.
pushed 1040
pushed 1
and then hangs, from here on
The complexity of the code is O(n^2). So, I don't think it has to do anything with that. Since the input can be at max 10^4 order. Moreover, according to the print debugging, I think the issue is with the input.
You have issue with input as you reach console line limit.
Put your input into a file should solve that issue.
Then you should be able to debug your algorithm which seems more complicated than needed.

Playing with Classes, Objects and Constructors / C++

I am trying to make a calculator application using c++, using a class and a constructor just to practice. I created a class including 4 functions, each for each operator. In the main function I used an if statement to choose the mathematical operator, a vector to store the inputs of the user. This vector is going to be carried out to the constructor of the class and to the functions respectively.
This is my code:
#include <iostream>
#include <vector>
using namespace std;
class Calc {
public:
Calc(vector<int> vec)
{
numbers = vec;
}
int add()
{
int total = numbers[0];
for (int i = 1; i <= numbers.size(); i++)
{
total += numbers[i];
}
return total;
}
int sub()
{
int total = numbers[0];
for (int i = 1; i <= numbers.size(); i++)
{
total = total - numbers[i];
}
return total;
}
int mul()
{
int total = numbers[0];
for (int i = 1; i <= numbers.size(); i++)
{
total = total * numbers[i];
}
return total;
}
int div()
{
int total = numbers[0];
for (int i = 1; i <= numbers.size(); i++)
{
total += numbers[i];
}
return total;
}
private:
vector<int> numbers;
};
int main()
{
int operation;
cout << "\nEnter the digit that corresponds to the wanted operation:\n1. +\n2. -\n3. *\n4. /\n\n";
cin >> operation;
if (operation != 1 && operation != 2 && operation != 3 && operation != 4)
{
cout << "Invalid entry.";
return 0;
}
cout << "\nEnter the numbers followed with a 0 to get the result: ";
int num = 1;
vector<int> nums;
while (num != 0)
{
cin >> num;
nums.push_back(num);
}
Calc Inputs(nums);
if (operation == 1)
{
cout << Inputs.add();
}
else if (operation == 2)
{
cout << Inputs.sub();
}
else if (operation == 3)
{
cout << Inputs.mul();
}
else if (operation == 4)
{
cout << Inputs.div();
}
else
{
cout << "Invalid entry.";
return 0;
}
}
The prgoram runs perfectly until I enter the numbers to calculate. Can anyone help me with finding out whats wrong with my code.
In C++ indexes start by 0 and go up to numbers.size() - 1.
numbers[numbers.size()]
will access the element after the last entry of the vector, aka. is out of bounds access and causes undefined behaviour, which can result in a segmentation fault.
Correct would be
for (int i = 0; i < numbers.size(); i++) { total += numbers[i]; }
or let the compiler do the hard work and use range based loops:
for(auto i : numbers) { total += i; }

My bubble sort is introducing values of '0' in array

I used a 'bubble-sort' for my C++ program, but it introduces random '0' values in array in a Fractional Greedy Program
int sorteaza()
{
int aux,schimb,i;
do
{
schimb=0;
for (i=0;i<=n;++i)
if (G[i][3]<G[i+1][3])
{
swap(G[i], G[i+1]);
}
}
while (schimb);
}
This is my entire code:
#include<iostream>
using namespace std;
int n; // Numarul de elemente
float G[100][3]; // Obiecte + detalii masa profit potenta
int masa = 0;
int read_data()
{
cout << "Greutatea Rucsac" << endl;
cin >> masa;
cout << "Obiecte: " << endl;
cin >> n;
for(int i = 1; i<=n;i++)
{
for(int j = 1; j<=2;j++)
{
cin >> G[i][j];
if(G[i][1] != 0 && G[i][2] != 0)
{
G[i][3] = G[i][2] / G[i][1];
}
}
}
}
// 2 500
// 4 500
int sorteaza()
{
int aux,schimb,i;
do
{
schimb=0;
for (i=0;i<=n;++i)
if (G[i][3]<G[i+1][3])
{
swap(G[i], G[i+1]);
}
}
while (schimb);
}
int verify()
{
for(int i = 1; i<=n;i++)
{
for(int j = 1; j<=3;j++)
{
cout << G[i][j];
cout << endl;
//G[i][3] = G[i][1] / G[i][2];
}
}
}
int greedy()
{
float profit = 0;
int i = 1;
int aux;
while(i<=n && masa>=0)
{
//cout << "G[i][1]: " << G[i][1] << endl;
if(masa>=G[i][1]) {
//cout << "Am ajuns aici";
profit=profit+G[i][2];
masa=masa-G[i][1];
}
else {
//cout << "Am ajuns dincolo";
aux= (masa*100)/G[i][1];
profit = profit + (aux * G[i][2])/100;
break;
}
i++;
}
cout << profit;
}
int main()
{
read_data();
sorteaza();
verify();
// greedy();
}
Learn to index all your arrays from zero.
float G[100][3];
Legal indexes are 0 to 99 and 0 to 2. So this code should be
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 2; j++)
{
cin >> G[i][j];
}
if (G[i][0] != 0 && G[i][1] != 0)
{
G[i][2] = G[i][1] / G[i][0];
}
}
and this code should be
if (G[i][2] < G[i+1][2])
{
swap(G[i], G[i+1]);
}
All your arrays start at zero. I'm sure you've been told this, but you have to start putting it into practise.
In general, write your for loops like this
for (int i = 0; i < N; ++i)
That's the correct loop for an array of size N.
You probably need <n instead of ≤n (that's where the uninitialized value i.e. 0 comes from). And you miss one loop in the bubble sort. Right now you're only bubbling the smallest element to the end of the list.
Also no idea what you're doing with that schimb and while condition.
Furthermore you're defining G as float[100][3] so you can't use G[i][3], only G[i][2].
int sorteaza()
{
int i,j;
for (i=0; i<n; i++)
{
for (j=i+1; j<n; j++)
{
if (G[i][2] < G[j][2])
{
swap(G[i], G[j]);
}
}
}
}

C++ Vector Subscript Issues

I was making an app that calculates the mean, median, and range of any integers, but I ran into the issue: Vector subscript out of range. I've looked at some other posts about this, and still haven't been able to fix it.
Here's my code:
#include <iostream>
#include <Algorithm>
#include <Windows.h>
#include <vector>
using namespace std;
int main() {
//Variables
int sze;
int mraw = 0;
double mean;
double median;
double range;
int fullnum = 0;
int lastnum = 1;
vector<int> med;
cout << "How many numbers do you have? ";
cin >> sze;
int *arr = new int[sze];
for (int i = 0; i < sze; i++) {
med.push_back(arr[i]);
}
//Getting numbers
for (int i = 0; i < sze, i++;) {
system("cls");
cout << "Enter number #" << i + 1 << ": ";
cin >> arr[i];
}
//Mean
for (int i = 0; i < sze; i++){
fullnum += arr[i];
}
mean = fullnum / sze;
//Median
sort(med.begin(), med.end());
int mvs = sze;
while (med.size() >= 2) {
med.erase(med.begin());
med.erase(med.begin() + med.size() - 1);
mvs--;
}
if (mvs == 2) {
mraw = med[1] + med[2];
median = mraw / 2;
}
else {
median = mvs;
}
//Range
vector<int> rnge;
for (int i = 0; i < sze; i++) {
rnge.push_back(arr[i]);
lastnum++;
}
sort(rnge.begin(), rnge.end());
int bigsmall[2];
bigsmall[1] = rnge[1];
bigsmall[2] = rnge[lastnum];
range = bigsmall[2] - bigsmall[1];
//Outputs
cout << "Mean: " << mean << "\nMedian: " << median << "\nRange: " << range;
system("cls");
return 0;
}
You have what would be an off-by-one error if lastnum was initialized to 0.
When rnge is empty, presumably lastnum is 0. This means access rnge[lastnum] is in error, as rnge is empty.
Applying an inductive argument shows that lastnum is the count of number of elements, and not the index of the last element. Thus, rnge[lastnum] is always out of range.
In actuality, you have initialized lastnum to 1, so your bug is actually off-by-two.

Debug error. R6010 abort has been called()

#include "../../../std_lib_facilities.h"
int main()
{
vector <int> nmb;
vector <int> rep;
vector <int> prt;
int flag = 0;
int temp = 0;
int br = 0;
int max = -1;
int ind = 0;
cout << "Enter as much integers as you like\n";
while (cin >> temp)
{
if (nmb.size() == 0)
{
nmb.push_back(temp);
prt.push_back(temp);
++rep[br];
++br;
}
else
{
for (int i = 0; i < nmb.size(); ++i)
{
if (temp == nmb[i])
{
++rep[i];
flag = 1;
}
}
if (flag == 0)
{
nmb.push_back(temp);
prt.push_back(temp);
++rep[br];
++br;
}
else if (flag == 1)
{
flag = 0;
prt.push_back(temp);
}
}
}
cout << "You've entered numbers\n";
for (int j = 0; j < prt.size(); ++j)
cout << prt[j] << " ";
for (int k = 0; k < rep.size(); ++k)
if (rep[k] > max)
{
max = rep[k];
ind = k;
}
cout << "\n\nMost repeated number is " << nmb[ind] << endl;}
My task is to write what number has been entered max times. I know it's probably not the best idea but it was the first "good" one I had so I went with it. It compiles fine but gives me that error from that title when running. I tried cout << in few places and it seems that problem starts at the beginning of while loop.
You try to access the first element of rep, which is an empty vector.
You have to actually add elements before you may access them. Right now you're reading from and writing to memory that is not yours.