The basic problem is that we (in pairs) have been tasked with creating a program to - amongst other things - read in a txt file and display it as a sudoku board as part of our introduction to coding at Uni.
We have completed most of the code and have got it working sufficiently well. However, we are struggling with what I would consider to be a basic aspect of this. The code reads in the file and saves it to the classes private char 9*9 matrix. We have run a debugging print-out to check that the values are being saved to the matrix and this is indeed the case. The issue is with the getMatrixVal(int x, int y) function which we think is returning a pointer rather than the character. We have tried returning a pointer from the function and have tried saving to a pointer and then to a char variable. Unfortunately, we am not excellent on pointer's.
With the recent suspensions to University timetables, we are temporarily unable to get the advice and support we require and, hence, we are applying here for advice.
Also, we are using the qt programming software on a raspberry pi - could this have anything to do with our problems?
#include "grid.h"
#include <QDebug>
#include <QChar>
#include <QFile>
grid::grid(char matrix_value, const int x, const int y) {
matrix[x][y] = matrix_value;
//char c = matrix[x][y];
//qDebug() << QChar(c);
}
void grid::load_file() {
QFile file("/home/pi/Documents/ELEC1204/P6/SUDOKU.txt");
char character, c;
int i, j;
if(!file.open(QFile::ReadOnly)) {
qDebug() << "Error in opening file";
return;
} //Print error if message if unable to open file
for(i = 0; i < 9; i++) {
for(j = 0; j < 9; j++) {
SKIP: //Related to 'goto'
file.read(&character, sizeof(char)); //Read ini individual characters
if(character == '\xd' || character == '\xa')
goto SKIP;
//Skip character related to new lines
//Goes to 'SKIP' point in program
else if(character == 'X')
grid('_', i, j);
//Save 'X's as '_'
else
grid(character, i, j);
//Save numbers as they are
c = getMatrixVal(i, j);
qDebug() << "i = " << i << "| j = " << j << "| Character is: " << QChar(character) << "| Matrix character is: " << QChar(c);
//Print-out for debugging
}
}
file.close();
//Close file
}
// Possibly useful source:
// https://doc.qt.io/qt-5/qfile.html
// https://forum.qt.io/topic/60240/reading-file-byte-by-byte/5
char grid::getMatrixVal(const int x, const int y) {
char c = matrix[x][y];
//qDebug() << "Matrix[" << x << "][" << y << "] is: " << QChar(c);
return c;
}
void grid::printMatrix() {
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
qDebug() << matrix[i][j];
}
}
}
//Prints out matrix
//Debugging function
There is nothing wrong with getMatrixVal: it returns a character from the right place in matrix.
Your call grid(character, i, j) constructs a new grid instance that is unrelated to the current one.
Instead, just assign directly to matrix: (or use a setter function)
matrix[i][j] = character;
Related
there is code.
#include "pch.h"
#include <algorithm>
#include <iostream>
#include <vector>
#include <stdlib.h>
using namespace std;
vector<int> SearchInt(vector<int> vec, int num) {
vector<int> temp(2);
sort(begin(vec), end(vec));
int j = 0;
for (int i : vec) {
if (i > num) {
temp[0] = i;
temp[1] = j;
return { temp };
}
//cout << i << " !>= " << num << endl ;
j++;
}
cout << "NO";
exit(0);
}
int main()
{
int n;
cin >> n;
vector<int> nums(n, 0);
vector<int> NewNums(n, 0);
for (int i = 0; i < n; i++) {
cin >> nums[i];
}
if (n != nums.size()) {
cout << "://";
return 0;
}
sort(begin(nums), end(nums));
NewNums[1] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
NewNums[0] = nums[nums.size() - 1];
nums.erase(nums.begin() + nums.size() - 1);
for (int j = 2; j <= NewNums.size() - 1; j++) {
NewNums[j] = SearchInt(nums, NewNums[j-1]- NewNums[j-2])[0];
nums.erase(nums.begin() + SearchInt(nums, NewNums[j] - NewNums[j - 1])[1]);
}
if (NewNums[NewNums.size()-1] < NewNums[NewNums.size() - 2] + NewNums[0]) {
cout << "YES" << endl;
for (int i : NewNums) {
cout << i << " ";
}
return 0;
}
else {
cout << "NO";
return 0;
}
}
His task is to check whether it is possible from the given Each number is less than the sum of the two adjacent ones.
(each number is less than both of two adjacent ones)
But there is a problem - with a large number of numbers, the code takes too long. Please help me to optimize it, or just give some advice.
numbers cаn not be null.
time limit: 3.0 s
n <= 500000
You are given n numbers a1, a2,…, an. Is it possible to arrange them in a circle so that each number is strictly less than the sum of its neighbors?
For example, for the array [1,4,5,6,7,8], the left array satisfies the condition, while the right array does not, since 5≥4 + 1 and 8> 1 + 6.
Input data
The first line contains one integer n (3≤n≤105) - the number of numbers.
The second line contains n integers a1, a2,…, an (1≤ai≤109) - the numbers themselves. The given numbers are not necessarily different.
Output
If there is no solution, print "NO" on the first line.
If it exists, print "YES" on the first line. After that, on the second line print n numbers - the elements of the array in the order in which they will stand on the circle. The first and last elements you print are considered neighbors on the circle. If there are multiple solutions, output any of them. You can print a circle starting with any of the numbers.
First I'll only briefly analyze technical shortcomings of your code - without analyzing its meaning. After that I'll write my solution of the problem you defined.
Performance problems of your code are due to some strange decisions:
(1) passing std::vector<int> by value and not by reference to SearchInt function - this implies allocating and copying of the whole array on each function invocation,
(2) call SearchInt two times per loop iteration in function main instead of only one,
(3) sort array within each invocation of SearchInt - it is already sorted before the loop.
To be honest your code feels ridiculously time-consuming. I'm only wondering if that was your intention to make it as slow as you possibly can...
I will not analyze correctness of your code according to problem description. To be honest even after fixing technical shortcomings your code seems to me utterly sub-optimal and quite incomprehensible - so it is just easier to solve the problem from scratch to me.
The answer to the problem as defined is YES if the biggest number is smaller than the sum of the second big and the third big and NO otherwise - this follows from the fact that all numbers are positive (in range 1 - 109 according to newly found problem description). If the answer is YES then to make a circle that satisfies the problem description you just need in a sorted sequence of input numbers switch places of the biggest number and the next big one - that's all.
Here is my code for that (for slightly relaxed input format - I'm not checking if number of items is on a separate line and that all items are on the same line - but all correct inputs will be parsed just fine):
#include <set>
#include <iostream>
int main()
{
std::multiset<unsigned> input_set;
unsigned n;
if( !( std::cin >> n ) )
{
std::cerr << "Input error - failed to read number of items." << std::endl;
return 2;
}
if( n - 3U > 105U - 3U )
{
std::cerr << "Wrong number of items value - " << n << " (must be 3 to 105)" << std::endl;
return 2;
}
for( unsigned j = 0; j < n; ++j )
{
unsigned x;
if( !( std::cin >> x ) )
{
std::cerr << "Input error - failed to read item #" << j << std::endl;
return 2;
}
if( x - 1U > 109U - 1U )
{
std::cerr << "Wrong item #" << j << " value - " << x << " (must be 1 to 109)" << std::endl;
return 2;
}
input_set.insert(x);
}
std::multiset<unsigned>::const_reverse_iterator it = input_set.rbegin();
std::multiset<unsigned>::const_reverse_iterator it0 = it;
std::multiset<unsigned>::const_reverse_iterator it1 = ++it;
if( *it0 >= *it1 + *++it )
{
std::cout << "NO (the biggest number is bigger than the sum of the second big and the third big numbers)" << std::endl;
return 1;
}
std::cout << "YES" << std::endl;
std::cout << "Circle: " << *it1 << ' ' << *it0;
do
{
std::cout << ' ' << *it;
}
while( ++it != input_set.rend() );
std::cout << std::endl;
return 0;
}
I am working on an assignment for school using hash tables in a structure program. Part of the assignment is writing a hash table composed of 20 primary buckets and 10 overflow buckets, each with 3 slots composed of a key and data field to disk and then restoring from it. Here is what I have so far:
#include <iostream>
#include <fstream>
#include <iomanip>
#include <stdio.h>
#include <string.h> // for strcpy()
using namespace std;
typedef char STR10[10+1];
typedef char STR20[20+1];
struct SLOT
{
STR10 key;
STR20 data;
};
struct BUCKET
{
SLOT entry[3];
int count;
BUCKET* overflow;
};
struct HASHTABLE
{
BUCKET pBkt[20];
BUCKET oBkt[10];
};
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk);
void ReportHT (HASHTABLE ht, char * when);
int main()
{
int maxP = 20;
int maxO = 10;
int maxS = 3;
HASHTABLE ht;
STR10 mKey;
STR20 mData;
FILE * inFile;
inFile = fopen("DATAIN.dat","rb");
if (inFile == NULL)
{
cout << " DATAIN file access error ... \n";
cout << " Terminating application ... \n ";
cout << " Press any key ... \n ";
return -100;
}
char crLF;
while (!feof(inFile))
{
fscanf(inFile,"%10c%20c\n",mKey,mData);
mKey[10] = mData[20] = 0; // add string terminators
printf(" MyKey: %10s\n MyData: %20s\n",mKey,mData);
cin.ignore(80,'\n'), cin.get();
//InsertIntoHT (ht, mKey, mData);
}
fclose(inFile);
WriteHTtoDisk(ht, "hashTable.dat");
ReportHT (ht,"BEFORE");
return 0;
}
void WriteHTtoDisk (HASHTABLE ht, char *HashDisk)
{
FILE * HASHDISK = fopen(HashDisk, "rb");
int maxBkt = 30;
int maxSlot = 3;
for (int i = 0; i < maxBkt; i++)
{
for (int j = 0; j < maxSlot; j++)
{
fwrite(ht.pBkt[i].entry[j].key,11,sizeof(maxSlot),HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,sizeof(maxSlot),HASHDISK);
}
}
}
void ReportHT (HASHTABLE ht, char * when)
{
int maxB = 30;
int maxS = 3;
cout << "Hash Table \n" << "Verification Report \n" << when << " Restoration" << endl;
for (int b = 0; b < maxB; b++)
{
cout << "Bucket " << (b+1) << endl;
if (b < 20)
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.pBkt[b].entry[i].key << setw(3) << ht.pBkt[b].entry[i].data << endl;
}
}
else
{
for (int i = 0; i < maxS; i++)
{
cout << setw(3) << "Slot " << (i+1) << ": " << ht.oBkt[b].entry[i].key << setw(3) << ht.oBkt[b].entry[i].data << endl;
}
}
}
}
The code compiles with no problems, but when I inspect the file, I find that it is all just gibberish and weird symbols. The data I am using was previously extracted from another file and I want to save it in the format in which it was inserted. I am sure the issue is with the lines with fwrite (I am not that experienced with C syntax as I am with C++).
The data was in the DATAIN.dat file like this:
TATUNG CO.EL PR. LONG BEACH CA
KAMERMAN LCIRRUS BEAVERTON, OR
QUADRAM COLOACH AV NORCROSS GE
AST RESEARALTON AV IRVINE CA
I am expecting the new file to look like this:
TATUNG CO.
EL PR. LONG BEACH CA
KAMERMAN L
CIRRUS BEAVERTON, OR
QUADRAM CO
LOACH AV NORCROSS GE
AST RESEAR
ALTON AV IRVINE CA
Any help would be greatly appreciated. Thank you.
It looks like your code doesn't initialize or even use the member count. When a hash bucket is empty, the count should indicate it. In C++ it's easy to implement: just add = 0 to its definition:
struct BUCKET
{
SLOT entry[3];
int count = 0;
BUCKET* overflow;
};
Also, when writing the bucket's data to a file, use the count and don't assume that all the entries in the bucket are filled.
for (int j = 0; j < ht.pBkt[i].count; j++)
...
Also, write only the required number of bytes. fwrite accepts two parameters: the size of the data elements to write and their number. Here, the size is 11 or 21, and the number is 1, because each fwrite call can only write one string to your file.
fwrite(ht.pBkt[i].entry[j].key,11,1,HASHDISK);
fwrite(ht.pBkt[i].entry[j].data,21,1,HASHDISK);
By the way, since you have a STR10 type, you can avoid magic numbers and write sizeof(STR10) instead of 11. This way, when you change the length of your string, your code will still work.
#include <stdio.h>
#include <stdlib.h>
double matrixMultiply(double a[100][100],double b[100][100], int rowA,int colB,int colArowB){
double c[100][100];
int i,j,k;
for(i=0;i<rowA;i++)
for(j=0;j<colB;j++){
for(k=0;k<colArowB;k++)
c[i][j]=c[i][j]+a[i][k]+b[k][j];}
return c;
}
int main()
{
double a[100][100],b[100][100];
int n,m,o,p,i,j;
printf("%s \n", "Nr. linii A:");
scanf("%d",&n);
printf("%s \n", "Nr. coloane A:");
scanf("%d",&m);
printf("%s \n", "Nr. linii B:");
scanf("%d",&o);
printf("%s \n", "Nr. coloane B:");
scanf("%d",&p);
printf("%s \n", "A=");
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d", &a[i][j]);
printf("%s \n", "B=");
for(i=0;i<o;i++)
for(j=0;j<p;j++)
scanf("%d", &b[i][j]);
if(m==o){
printf("Matricile se pot inmulti");
cout<<matrixMultiply(a,b,n,m,p);
return 0;}
else printf("Matricile nu se pot inmulti");
return 0;
}
I should multiply 2 matrices A & B, but I don't know how to return the matrix C, can somebody help?
There is an error returning the matrix C,also do I need a for to print the matrix C?
I should multiply 2 matrices A & B, but I don't know how to return the matrix C, can somebody help?
return c;
will not work since the array decays to a pointer. Not only that, the pointer becomes invalid as soon as the function returns since c is a function local variable.
If the size of the matrix is known at compile time, you may use std::array. If the size of the matrix is known at run time only, you should use std::vector of std::vector.
std::array<std::array<int, 100>, 100> matrixMultiply(...) {}
or
std::vector<std::vector<int>> matrixMultiply(...) {}
As others have stated you could use the std::vector<std::vector<int>> but if you still want to use a 2D, array you need to dynamically allocate the 2D array in the function using a malloc and return a double* matrixMultiply(double a[100][100],double b[100][100], int rowA,int colB,int colArowB) or you could also allocate in the main function and just pass the address reference cout<<matrixMultiply(&a,&b,n,m,p);
vector maybe a better choice for this case in C++.
the function maybe looks like the following, and the entire program for this question is here
using namespace std;
typedef vector<double> MatrixRow;
typedef vector<MatrixRow> Matrix;
Matrix matrix_multiply(const Matrix &left, const Matrix &right)
{
// Validate conditions of multiplication of matrices
if (left.empty())
{
cerr << "Left matrix is empty." << endl;
exit(-1);
}
if (right.empty())
{
cerr << "Right matrix is empty." << endl;
exit(-1);
}
const int leftRowCount = left.size();
const int leftColumnCount = left.front().size();
const int rightRowCount = right.size();
const int rightColumnCount = right.front().size();
if (leftColumnCount != rightRowCount)
{
cerr << "The number of columns of the left matrix is not the same as the number of columns of the right matrix." << endl;
exit(-1);
}
cout << "Calculate steps" << endl
<< "=====" << endl;
// Calculation
Matrix matrix(leftRowCount);
for (int i = 0; i < leftRowCount; i++)
{
matrix.at(i).resize(rightColumnCount);
for (int j = 0; j < rightColumnCount; j++)
{
matrix.at(i).at(j) = 0;
cout << "M(" << i << "," << j << ") = ";
for (int k = 0; k < leftColumnCount; k++)
{
cout << "L(" << i << "," << k << ") + R(" << k << "," << j << ")";
if (k < leftColumnCount - 1)
{
cout << " + ";
}
matrix.at(i).at(j) += left.at(i).at(k) * right.at(k).at(j);
}
cout << endl;
}
}
cout << endl;
return matrix;
}
More about identifier naming:
In declarations
An identifier can be used to name objects, references,
functions, enumerators, types, class members, namespaces, templates,
template specializations, parameter packs, goto labels, and other
entities, with the following exceptions:
the identifiers that are keywords cannot be used for other purposes;
the identifiers with a double underscore anywhere are reserved; the
identifiers that begin with an underscore followed by an uppercase
letter are reserved;
the identifiers that begin with an underscore are
reserved in the global namespace.
more about identifier naming in C++, visit here for details.
I have an assignment with several ways to manipulate an array, but I'm having trouble with one of the parts.
I am reading about 50 numbers into the array from a .txt file
And for every odd location in the array (1,3,5,…), I have to subtract it from the previous even location (0,2,4,…) and store results in the odd location. Then I print out all values in the array.
Here is what I have so far:
void oddMinusEven(int ary[],int num)
{
for(int idx = ary[0]; idx<num; ary[idx+2])
{
ary[idx] = ary[idx+2]-ary[idx];
cout<<ary[idx]<<endl;
}
}
How do I do this? If you could provide some examples, that would be great.
This should do:
void oddMinusEven(int ary[], int num) {
for(int i = 1; i < num; i += 2) {
ary[i] = ary[i-1] - ary[i];
std::cout << "a[" << i << "] = " << ary[i] << std::endl;
}
}
I basically want to pass this array of data I'm reading to diffent functions and eventually plot it.
The array contains a 32 bit word of '1's and '0's, I then want to add these individual bits together to see where my data spikes. So in other words if I add "0100" to "0110" I get "0210" - which is probably easier done with separate bins and plotting.
At the moment I'm just getting garbage out.
void binary(int convert, int* dat) {
bitset<32> bits(convert);
//cout << bits.to_string() << endl;
char data[32];
for(unsigned i = 0; i < 32; ++i) {
data[i] = bits[i];
}
for(unsigned i = 32; i; --i) {
dat[i] = (int(data[i-1]))+dat[i];
}
}
void SerDi() {
int dat[32];
cout << " Reading data from memory..." << endl;
ValVector< uint32_t> data=hw.getNode("SerDi.RAM").readBlock(8);
hw.dispatch();
cout << data[0]<<endl;
cout << data[1]<<endl;
for (unsigned i = 2; i < 7; i++) {
binary(data[i], dat);
}
cout << dat[7] << endl;
graph(dat); //passes the array to a place where I can plot the graph
}
You have
int dat[32];
But in convert you have i = 32 and dat[i] That will access something outside of the array and bad things will happen.
Also that is not initialized. Add a memset/loop somewhere to make dat initially 0.