Reading Floats from a txt file in C++ - c++

I am trying to read (x,y) floating point values from a txt file in C++. The numbers are separated by a space. The ith number and the i+1th number make the (x,y) coordinates. So index positions 0 and 1 would be the first (x,y) pair and index positions (1,2) would be the next (x,y) pair.
This is what I have done but I am not sure how I can save them as floats.
ifstream randomFile;
string content;
randomFile.open("random.txt");
if(randomFile.is_open()) {
while(getline(randomFile,content)){
randomFile >> content;
}
randomFile.close();
}

Read the first float x
While additional read y succeeds:
  Add (x, y) to your list
  x = y
#include <iostream>
#include <vector>
struct xy
{
float x, y;
xy( float x, float y ) : x{x}, y{y} { }
};
auto read_xy_pairs( std::istream & ins )
{
std::vector<xy> xys;
float x, y;
ins >> x;
while (ins >> y)
{
xys.emplace_back( x, y );
x = y;
}
return xys;
}
#include <sstream>
#include <string>
int main()
{
std::cout << "list of numbers? ";
std::string s;
getline( std::cin, s );
std::istringstream numbers( s );
for (auto [x, y] : read_xy_pairs( numbers ))
std::cout << "(" << x << ", " << y << ")\n";
}
Example:
list of numbers? 1 2 3 4 5
(1, 2)
(2, 3)
(3, 4)
(4, 5)

An extra variable (prev) can be used to store the value of last input and append (prev,curr) on every iteration to the storage container. In the following code, I have used vector of pairs of float to store the pairs, but you may use arrays or structures as well.
#include<fstream>
#include<iostream>
#include<vector>
using namespace std;
int main() {
//Declaring vector of float pairs
vector <pair<float, float>> floatPairs;
ifstream randomFile;
float curr, prev;
randomFile.open("a.txt");
randomFile >> curr;
while (!randomFile.eof()) {
prev = curr;
randomFile >> curr;
//Appending to vector of float pairs
floatPairs.push_back({ prev,curr });
}
//Printing
for (auto i : floatPairs) {
cout << "(" << i.first << ", " << i.second << ")\n";
}
}
Input file content: 12.5 56.8 34.7 75.7 23.4 86.7 34.9 66.8
Output:
(12.5, 56.8)
(56.8, 34.7)
(34.7, 75.7)
(75.7, 23.4)
(23.4, 86.7)
(86.7, 34.9)
(34.9, 66.8)

Related

Assign TicTacToe player position to a bitboard representation

I have 2 separate boards for 2 players: X and O. Now I'd like to make sure if an entered position (int x, int y) is valid but I've got no idea of how should I convert it to bitboard representation and compare it with given board states and it's doing me head in. Also wrote a helper function to see the board states bin(). And is there a way to merge the X and O boards into one or should I keep the separate all board to check the game state?
#include <bits/stdc++.h>
using namespace std;
bool xmove = true;
const int win[] = { 0b111000000,
0b000111000,
0b000000111,
0b100100100,
0b010010010,
0b001001001,
0b100010001,
0b001010100 };
struct Board {
int b = 0b000000000;
};
int iswin(int x) {
for (size_t i = 0; i < 8; i++) {
if (win[i] == x) return 1;
}
return 0;
};
void bin(int x){
cout << "0b" + bitset<9>(x).to_string() << endl;
};
int main() {
Board x, o, all;
x.b |= 0b000000111;
o.b |= 0b000111000;
all.b = x.b | o.b;
bin(all.b);
cout << iswin(x.b);
return 0;
}
Well you can treat your bitstring as a flattened 2d array. To convert a 2d index into a 1d one you can simply do
x * width + y
So to set the matching position in the board you can do
int move = 1 << (x * 3 + y)
since a TicTacToe board is 3 wide and 3 tall. You can then check if there already is an X or O at that position with
if(x.b & move)
{
std::cout << "there already is and x at(" << x << ", " << y << ")";
}
To then add that position to the board if there is nothing there do
x.b |= move
Same thing for o.b. This is of course based on the assumption that your x and y start at 0.
Concerning your question of whether or not you can merge the two board. How would you even do that? A bit can only be 0 or 1 so there is no way to differentiate between 3 different states (nothing, X, O).

Terminate called after throwing an instance of 'std::invalid_argument' what(): stof

As I was writing the in the other post, I am trying to implement the K-means algorithm in C++. When debugging, I get no errors, but when trying to run the program, I get the error I mentioned in the title:
Terminate called after throwing an instance of 'std:invalid_argument' what():stof
I know that this error comes when the file can't convert to float. Then, what I wanted to ask is, is there something that I should change in my code, or would it be better to use another file format as input, instead of a *.csv file ? (obviosuly, I'm making the hypothesis that the program can't read something from the file. I don't know if that's the right reasoning though.)
Thank you everyone!
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
using namespace std;
//Inizializzare il punto
struct Point {
double x, y; // Coordinate del punto
int cluster; // Cluster di default
double minDist; // Distanza minima
Point()
: x(0.0)
, y(0.0)
, cluster(-1)
, minDist(__DBL_MAX__)
{
}
Point(double x, double y)
: x(x)
, y(y)
, cluster(-1)
, minDist(__DBL_MAX__)
{
}
double distance(Point p)
{
return (p.x - x) * (p.x - x) + (p.y - y) * (p.y - y);
}
};
vector<Point> readcsv()
{
vector<Point> points;
string line;
ifstream file("Mall_Customers.csv");
while (getline(file, line)) {
stringstream lineStream(line);
string bit;
double x, y;
getline(lineStream, bit, ',');
x = stof(bit);
getline(lineStream, bit, '\n');
y = stof(bit);
points.push_back(Point(x, y));
}
return points;
}
vector<Point> points = readcsv();
void kMeansClustering(vector<Point>* points, int epochs, int k)
{
int n = points->size();
vector<Point> centroids;
srand(time(0));
for (int i = 0; i < k; ++i) {
centroids.push_back(points->at(rand() % n));
}
for (vector<Point>::iterator c = begin(centroids); c != end(centroids); ++c) {
int clusterId = c - begin(centroids);
{
for (vector<Point>::iterator it = points->begin(); it != points->end(); ++it) {
Point p = *it;
double dist = c->distance(p);
if (dist < p.minDist) {
p.minDist = dist;
p.cluster = clusterId;
}
*it = p;
}
}
}
vector<int> nPoints;
vector<double> sumX, sumY;
for (int j = 0; j < k; j++) {
nPoints.push_back(0.0);
sumX.push_back(0.0);
sumY.push_back(0.0);
}
for (vector<Point>::iterator it = points->begin(); it != points->end(); ++it) {
int clusterId = it->cluster;
nPoints[clusterId] += 1;
sumX[clusterId] += it->x;
sumY[clusterId] += it->y;
it->minDist = __DBL_MAX__; // reset distance
}
// Compute the new centroids
for (vector<Point>::iterator c = begin(centroids); c != end(centroids); ++c) {
int clusterId = c - begin(centroids);
c->x = sumX[clusterId] / nPoints[clusterId];
c->y = sumY[clusterId] / nPoints[clusterId];
}
// Write to csv
ofstream myfile;
myfile.open("output.csv");
myfile << "x,y,c" << endl;
for (vector<Point>::iterator it = points->begin(); it != points->end();
++it) {
myfile << it->x << "," << it->y << "," << it->cluster << endl;
}
myfile.close();
}
int main()
{
vector<Point> points = readcsv();
// Run k-means with 100 iterations and for 5 clusters
kMeansClustering(&points, 100, 5);
}
It seems to work now, thank you everyone for the help you gave me, in particular #Yksisarvinen and #molbdnilo : the problem was in the fact that I blindly imported all the csv file in the program, but I was supposed to import only two columns: one was the income, the other one was the spending column.
Although now I have to figure why it shows me the final result, not in the form of "bubbles",as one would expect from the algorithm,but in the form of points being clustered on a straight line.
When trying to open the original file, the original dataset, I get the error shown in the image below.

hostel visit question (priority queue application )

question: Dean of MAIT is going to visit Hostels of MAIT. As you know that he is a very busy person so he decided to visit only the first "K" nearest Hostels. Hostels are situated on a 2D plane. You are given the coordinates of hostels and you have to answer the Rocket distance of Kth nearest hostel from the origin ( Dean's place )
Input Format
The first line of input contains Q Total no. of queries and K There are two types of queries:
first type: 1 x y For query of 1st type, you came to know about the coordinates ( x, y ) of the newly constructed hostel. second type: 2 For query of 2nd type, you have to output the Rocket distance of Kth nearest hostel till now.
//The Dean will always stay at his place ( origin ). It is guaranteed that there will be at least k queries of type 1 before the first query of type 2.
Rocket distance between two points ( x2 , y2 ) and ( x1 , y1 ) is defined as (x2 - x1)2 + (y2 - y1)2
Constraints
1 < = k < = Q < = 10^5 -10^6 < = x , y < = 10^6
Output Format
For each query of type 2 output the Rocket distance of Kth nearest hostel from Origin.//
This is my code:
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
class roomno
{
public:
int x;
int y;
roomno(int x,int y)
{
this->x=x;
this->y=y;
}
void print()
{
cout<<"location"<<"("<<x<<","<<y<<")"<<endl;
}
int distance ()
{
return (x*x+y*y);
}
};
class roomcompare
{
public:
bool operator() (roomno r1,roomno r2)
{
return r1.distance()>r2.distance();
}
};
int main()
{
int x[1000]},y[1000];
int l,k=0;
priority_queue<roomno,vector<roomno>,roomcompare> pq;
int n,i,j;
cin>>n>>l;
//cin>>n;
cin.ignore();
for( i=0;i<n;i++)
{
cin>>x[i];
}
cin.ignore();
for( j=0;j<n;j++)
{
cin>>y[j];
}
cin.ignore();
for(i=0;i<n;i++ )
{
roomno r1(x[i],y[i]);
pq.push(r1);
}
while(!pq.empty()&&k!=l)
{ k++;
roomno r2=pq.top();
r2.print();
pq.pop();
}
return 0;
}
Original link to code: https://codeshare.io/2j1bkA
What's wrong with my code?
Please consider adding what problem you are facing in your post. I've seen your code but I couldn't help with your code as I even saw a syntax error in your code and didn't know if it was the problem.
If I didn't misunderstand your question, std::set will fit better than priority queue as it is not possible to remove the largest item in a priority queue(min heap). The following code should work:
#include <iostream>
#include <set>
using namespace std;
using ll = long long;
multiset<ll> distances;
int main() {
ll n, k;
cin >> n >> k;
for(ll i = 0; i < n; ++i) {
ll query;
cin >> query;
if (query == 1) {
ll x, y;
cin >> x >> y;
distances.insert(x * x + y * y);
if (distances.size() > k) {
distances.erase(--distances.end());
}
} else {
cout << *distances.rbegin() << '\n';
}
}
return 0;
}

C++ vectors of values returning a matrix

I have 4 integer variables - x,y,z,t which could get values from an interval of integer values [a,b] ) ( the interval is a,a+1,a+2,...,b ).
I want to set a vector of distinct {x,y,z,t} values with the following rule:
2 quartets (x and y) are not equal if there exists at least one quartet value for which : x.i != y.i (i is one of the {x,y,z,t} value positions).
My current solution is extremely time consuming:
struct gim
{
int xx;
int yy;
int zz;
int tt;
}
vector<gim> v;
x=a;y=a;z=a;t=a;
nr_quartet=0;
gim g;
while(x<=b)
{
while(y<=b)
{
while(z<=b)
{
while(t<=b)
{
if(at least one of x,y,z,t is different)
{
nr_quartet++;
g.xx=x;
g.yy=y;
g.zz=z;
g.tt=t;
v.push_back(g);
cout << x << " " << y << " " << z << " " << t << "\n";
}
t++;
}
z++;
}
y++;
}
x++;
}
You can try something like this:
int actual_t = t;
int actual_z = z;
int actual_y = y;
int actual_x = x;
while(t<=b && z <=b && y<=b && x<=b)
{
if(at least one of x,y,z,t is different)
{
nr_quartet++;
v.emplace_back(x, y, z, t);
//cout << x << " " << y << " " << z << " " << t << "\n";
}
// For t
if(t==b)
{
t = 0;
}
else
{
t++;
}
actual_t = t;
// For z
if(z==b)
{
z = 0;
}
else if(/* incrementation condition for z */)
{
z++;
}
actual_z = z;
/* the same for y and x */
}
If you only need the number of elements of the set {(x,y,z,t) | ¬(x = y = z = t)}, then compute (b-a)**4 - (b-a); i.e. no need to iterate through all of them.
If you really need to fill a vector with all the combinations, well, you will have to iterate to add them all. The longest part will be memory allocations inside the std::vector, so pre-reserve or pre-resize with the number of elements since you can know it in advance.
As far as I've done is something which is consuming much time
What do you mean it is consuming a lot of time? What is your [a, b] range?

Why does this seemingly simple C++ code generate a segmentation fault?

I'm trying to write a boosting algorithm (a feature of artificial intelligence). Speed is a priority, so I've switched from using my native Python to C++. I wrote the entire program out, but I got a bug that I whittled down to a fault I made in the base class: a very simple heuristic called "H." The files h.h, h.cpp, and my current testing function main.cpp are:
//h.h
#ifndef __H_H_INCLUDED__
#define __H_H_INCLUDED__
#include <iostream>
#include <vector>
class H
{
public:
H(int, double, bool);
//The first parameter is the axis
//The second parameter is the cutoff
//The third parameter is the direction
bool evaluate(std::vector<double>&);
//This evaluates the heuristic at a given point.
private:
int axis;
double cutoff;
bool direction;
};
#endif
//h.cpp
#include "h.h"
H::H(int ax, double cut, bool d)
{
axis = ax;
cutoff = cut;
direction = d;
}
bool H::evaluate(std::vector<double>& point)
{
if (direction)
{
return point[axis] > cutoff;
}
else
{
return point[axis] <= cutoff;
}
}
//main.cpp
#include <iostream>
#include <vector>
#include "h.h"
int main()
{
H h(0, 2.0, true);
for (double x = 0; x < 4; x = x + 1)
{
for (double y = 0; y < 4; y = y + 1)
{
std::vector<double> point(x, y);
std::vector<double>& point_ref = point;
std::cout << "Before computation" << std::endl;
bool value = h.evaluate(point_ref);
std::cout << "After computation" << std::endl;
std::cout << "heuristic(x = " << x << ", y = " << y << ") = " << value << std::endl;
}
}
return 0;
}
(I put the "Before computation" and "After computation" in to pinpoint which line the error occurs on.) Quite contrary to the output I would expect, I get:
Before computation
Segmentation fault (core dumped)
What did I do wrong? What does that error message even mean?
Thanks!
EDIT: I'm using C++11, just for those who are curious.
This line:
std::vector<double> point(x, y);
Makes a vector with x copies of y. It's constructor #2 here. So when x is 0, point is an empty vector - which means your access of the element at index 0 is undefined behavior, in this case exhibited by a segmentation fault.
What you probably had intended to do was to make a vector containing the two values x and y, which would be:
std::vector<double> point{x, y}; // in c++11, note the braces
std::vector<double> point(2); // pre-c++11
point[0] = x;
point[1] = y;