Putting values from one Array into another - visual-c++

I'm at a loss here, so I am looking for any hints to point me in the right direction. I can't figure out how to input the Celsius values that I converted from the Fahrenheit temperatures into the centigrade array. I tried to work in another for loop for that very purpose but it only outputs the last value for C after the calculation from the first for loop. Any ideas? Thanks in advance.
// Temperature Converter
#include <iostream>
#include <iomanip>
using std::cout;
using std::endl;
using std::setw;
int main()
double temps[] = { 65.5, 68.0, 38.1, 75.0, 77.5, 76.4, 73.8, 80.1, 55.1, 32.3, 91.2, 55.0 };
double centigrade[] = { 0 }, C(0);
int i(0);
cout << setw(13) << "Farenheit " << setw(9) << " Centigrade";
cout << endl;
for (double t : temps)
{
C = (t - 32) * 5 / 9;
cout << setw(10) << t << setw(12) << C;
cout << endl;
}
for (i = 0; i <= 12; i++)
{
centigrade[i] = C;
cout << centigrade[i] << endl;
}
return 0;
}

Here is a full working example based on the other answer.
#include <iostream>
using std::cout;
using std::endl;
int main() {
double temps[] = { 65.5, 68.0, 38.1, 75.0, 77.5, 76.4, 73.8, 80.1, 55.1, 32.3, 91.2, 55.0 };
const int count = sizeof(temps) / sizeof(temps[0]);
double centigrade[count];
for (int i = 0; i < count; i++) {
centigrade[i] = (temps[i] - 32) * 5 / 9;
cout << centigrade[i] << endl;
}
return 0;
}
If you want to work without an explicit indexing loop, then replace double centigrade[count]; with std::vector<double> centigrade, and replace the loop with:
for (double t : temps)
centigrade.push_back((t - 32) * 5 / 9);
If you then wanted an array back for some reason, you could use this trick to get an array back:
double* array_version = &centigrade[0];

Store values in the array in the first loop itself..
for (i=0;i<=12;i++)
{
centigrade[i]= (temps[i] - 32) * 5 / 9;
cout << setw(10) << temps[i] << setw(12) << centigrade[i];
cout << endl;
}
U can generalize the for loop by finding the size of temps array dynamically..maybe
sizeof (temps) / sizeof (temps[0]);
Also allocate memory for centigrade array accordingly.

I am adding a new answer based on clarifications to the OP's question, rather than updating my existing answer, because I feel the context is more clear this way.
If you want to use a range-based loop, and avoid std::vector, there is a way to do it, but this solution is more in the spirit of C thanC++, because it uses pointer arithmetic.
#include <iostream>
using std::cout;
using std::endl;
int main() {
double temps[] = { 65.5, 68.0, 38.1, 75.0, 77.5, 76.4, 73.8, 80.1, 55.1, 32.3, 91.2, 55.0 };
const int count = sizeof(temps) / sizeof(temps[0]);
double centigrade[count];
double * walker = centigrade;
for (double t : temps)
*walker++ = (t - 32) * 5 / 9;
// verify results by printing.
for (double t: centigrade)
cout << t << endl;
return 0;
}

Related

I'm trying to make a loop to draw multiple lines in cairo but it stops drawing after the first iteration

I'm making a program where a person can input a direction and in the if statement, it adds/subtracts x/y axis and it draws a line after it gets over. The problem is that for some reason, it only works at the first iteration and doesn't draw any more lines after that.
I added a cin >> x >> y to test it out but it only draws one line and doesn't draw anymore.
Initially, the choices were in a switch statement but I changed to if because I thought that was causing the error.
#include "pch.h"
#include <iostream>
#include <fstream>
#include <string.h>
#include <cairo.h>
#define _USE_MATH_DEFINES
#include <math.h>
using namespace std;
char b = NULL;
char u = 'œ';
char d = 'd';
int main()
{
cairo_surface_t *surface = cairo_image_surface_create_from_png("background.png");
cairo_t *cr = cairo_create(surface);
cairo_set_source_rgb(cr, 0, 0, 0);
cairo_set_line_width(cr, 5);
double x = 0, y = 240;
cairo_move_to(cr, x, y);
long int count = 0;
int cl = 0;
int crr = 0;
int choice = 0;
int n;
system("cls");
while (choice != 5)
{
cin >> x >> y;
cairo_line_to(cr, x, y);
cairo_stroke(cr);
cairo_surface_write_to_png(surface, "spiral.png");
cout << "Current no. of points are : " << count << "/4096" << endl;
cout << "Enter direction: \n" << endl;
cout << "1 - Top Left \t 2 - Up \t 3 - Top Right " << endl;
cout << "4 - Left \t 5 - Stop \t 6 - Right" << endl;
cout << "7 - Bot. Left \t 8 - Down \t 9 - Bot. Right" << endl << endl;
cout << "Enter you choice: ";
cin >> choice;
if (choice == 1)
cout << "Test";
else
{
//More choices include the direction the person needs to go and it subtracts/adds to the x/y part
cout << "How many times ?: ";
cin >> n;
for (int i = 1; i <= n; i++)
{
x++;
count++;
cl++;
if (cl == 256)
{
cl = 0;
crr++;
}
}
system("cls");
}
}
}
I expect it to draw lines to a particular direction. Say the person inputs right, it draws a line towards right and so on. But here, no lines get drawn at all (except if I add a cin >> x >> y at the start of the while loop, that draws one line and that's it, no more lines.)
This fails because there is no current point anymore. After cairo_stroke(cr);, you can add cairo_move_to(cr, x, y); and it should start drawing more lines in the way you expect. I think... I'm not quite sure what you are up to with this program.

MPI_Gather Vector of Objects

I am writing a mpich program for parallel sorting. I need to use the mpi_gather interface, but it doesn't support passing vector of objects. So I use boost_serialization.
Implementation
I use boost_serialization to serialize the vector.
std::string serial_str;
boost::iostreams::back_insert_device<std::string> inserter(serial_str);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> s(inserter);
boost::archive::binary_oarchive send_ar(s);
//samples is the vector<object>
send_ar << samples;
s.flush();
int len = serial_str.size();
Then, I use mpi_gather to send all the serial_str to root process(data_recv).
char *data_recv = NULL;
if(myid == 0){
data_recv = (char*)malloc(sizeof(char) * (len_all+1));
data_recv[len_all] = '\0';
}
MPI_Gather((void*)serial_str.data(), len, MPI_BYTE, data_recv, len, MPI_BYTE, 0, MPI_COMM_WORLD);
Finally, I deserialize the data in data_recv.
boost::iostreams::basic_array_source<char> device(data_recv,len_all);
boost::iostreams::stream<boost::iostreams::basic_array_source<char>> s(device);
boost::archive::binary_iarchive recv_ar(s);
std::vector<mdata> recv_vec;
recv_ar >> recv_vec;
My implementation is based on How to send a set object in MPI_Send
Problem
I can't deserialize the data in data_recv correctly. I printed the data_recv, then I found the data in data_recv is incorrectly formatted after mpi_gather. The second archive covered the first.(marked in bold)
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222serialization::archive000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
The correct format should be:(no overlap so I can deserialize)
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
serialization::archive
XylvXe-M X 00000000000000000000000000002595 DDDDFFFFCCCCBBBB111133332222DDDD333388888888FFFF2222O#f&!O,t.b X 000000000000000000000000000023D0 EEEE7777EEEE44447777BBBB8888AAAA0000AAAAAAAAFFFF1111
Question
Why did this happen? Is it because the mpi_gather isn't compatible with c++ object?
If someone could help me out, it would solve my big problem.
Thank you!
code
//processor rank, and total number of processors
int myid, world_size;
//for timing used by root processor
double startwtime = 0.0, endwtime;
//init MPI World
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Comm_rank(MPI_COMM_WORLD, &myid);
//get the processor name
char processor_name[MPI_MAX_PROCESSOR_NAME];
int name_len;
MPI_Get_processor_name(processor_name,&name_len);
//read local data
std::vector<mdata> mdatas;
string data_path = "/home/jiang/mpi_data";
readAsciiData(data_path, mdatas);
cout <<"rank: "<<myid <<" mdata_vector.size(): "<<mdatas.size()<<endl;
//local sort according ASCII order
std::sort(mdatas.begin(), mdatas.end());
//regular sample
std::vector<mdata> samples;
for(int i=0; i<mdatas.size(); i=i+mdatas.size()/world_size){
samples.push_back(mdatas[i]);
}
//gather the regular samples
//passing data in byte stream by using boost serialization
std::string serial_str;
boost::iostreams::back_insert_device<std::string> inserter(serial_str);
boost::iostreams::stream<boost::iostreams::back_insert_device<std::string>> s(inserter);
boost::archive::binary_oarchive send_ar(s);
send_ar << samples;
s.flush();
int len = serial_str.size();
//int len = s.str().size();
int *pivot_lens = NULL;
if(myid == 0){
pivot_lens = (int*)malloc(sizeof(int) * world_size);
}
cout <<serial_str <<endl;
//first, gathering the lens and calculate the sum
cout << "rank " << myid << " on "<< processor_name << " is sending len: "<< len << endl;
MPI_Gather(&len, 1, MPI_INT, pivot_lens, 1, MPI_INT, 0, MPI_COMM_WORLD);
//calculate the sum of lens
int len_all = 0;
if(myid == 0){
for(int i=0;i<world_size;i++){
len_all = len_all + pivot_lens[i];
//cout << pivot_lens[i] << endl;
}
cout << "len_all:" << len_all << endl;
free(pivot_lens);
}
//then, gathering string of bytes from all the processes
char *data_recv = NULL;
if(myid == 0){
data_recv = (char*)malloc(sizeof(char) * (len_all+1));
data_recv[len_all] = '\0';
}
MPI_Gather((void*)serial_str.data(), len, MPI_BYTE, data_recv, len, MPI_BYTE, 0, MPI_COMM_WORLD);
// cout << serial_str <<endl;
if(myid == 0){
//deconstructe from byte of string to vector<mdata>
boost::iostreams::basic_array_source<char> device(data_recv,len_all);
boost::iostreams::stream<boost::iostreams::basic_array_source<char>> s(device);
boost::archive::binary_iarchive recv_ar(s);
std::vector<mdata> recv_vec;
recv_ar >> recv_vec;
int count =0;
for(int i=0;i<len_all;i++){
cout<<data_recv[i];
count ++;
}
cout <<endl <<count ;
cout <<endl;
//cout << "rank " << myid << " gets the samples: " << recv_vec.size()<<endl;
iterateForTest(myid, recv_vec);
free(data_recv);
}
MPI_Finalize();
return 0;

How to solve http://www.spoj.com/problems/MST1/ in n is 10^9

Using Bottom to up DP approach, I am able to solve the problem How to solve http://www.spoj.com/problems/MST1/ upto 10^8.
If input is very large n upto 10^9. I will not be able to create lookup table for upto 10^9. So what will be better approach to solve the problem ?
Is there any heuristic solution ?
#include <iostream>
#include <climits>
#include <algorithm>
using namespace std;
int main()
{
const int N_MAX = 20000001;
int *DP = new int[N_MAX];
DP[1] = 0;
for (int i = 2; i < N_MAX; i++) {
int minimum = DP[i - 1];
if (i % 3 == 0) minimum = min(minimum, DP[i/3]);
if (i % 2 == 0) minimum = min(minimum, DP[i/2]);
DP[i] = minimum + 1;
}
int T, N; cin >> T;
int c = 1;
while (T--) {
cin >> N;
cout << "Case " << c++ << ": " << DP[N] << endl;
}
delete[] DP;
}

End1 not declared C++

When I try to build the solution for this program I am receiving the error End1 Not declared for all the end1 statements. Am I missing something?
#include "StdAfx.h
#include <iostream>
using namespace std;
const double PI = 3.14;
int main()
{
double circumference;
double radius;
double area;
cout << "Enter the radius: ";
cin >> radius;
cout << end1;
circumference = 2 * PI * radius;
cout << "Circumference = " << circumference << end1;
area = PI * radius * radius;
cout << "Area = " << area << end1;
return 0;
}
Try replacing the number 1 with the letter l
http://en.cppreference.com/w/cpp/io/manip/endl
replace end1 with endl
cout << "Circumference = " << circumference << endl;

Why am I getting an assertion error?

#include <iostream>
using namespace std;
int main ()
{
int size = 0;
int* myArray = new int [size + 1];
cout << "Enter the exponent of the first term: ";
cin >> size;
cout << endl;
for (int i = size; i >= 0; --i)
{
cout << "Enter the coefficient of the term with exponent "
<< i << ": ";
cin >> myArray[i];
}
for (int i = size; i >= 0; --i)
{
cout << i << endl;
}
return 0;
}
Why am I getting an assertion error on input greater than 2? This is the precursor to a polynomial program where the subscript of the array is the power of each term and the element at array[subscript] is the coefficient.
Your array is allocated to be an int[1]. It needs to be allocated after you read in the size value.
You are initializing your array when size = 0, giving an array size of 1
You get your assertion error when you go outside of the array bounds (1).
myArray always has size 0 + 1 = 1. i starts out at whatever the user inputted, and the first array access you make is myArray[i]. So, say the user inputs 5, your array has size 1 and you access myArray[5]. It will fail!
I would allocate the array AFTER you input size.

Resources