How to use typedef in function? - c++

I am coding Quicksort to sort binary files that contains different data type(structs). This is what i wrote so far:
void quicksort(){
int izbor;
char naziv_datoteke[20];
cout << "Izaberite datoteku koju zelite sortirati: "<<endl;
cout << "1 - sifra.ind "<<endl;
cout << "2 - ime.ind "<<endl;
cout << "3 - prezime.ind "<<endl;
cin >>izbor;
switch(izbor){
case 1:strcpy(naziv_datoteke, "sifra.ind");
typedef tsifra slog;
break;
case 2:strcpy(naziv_datoteke, "ime.ind");
typedef time slog;
break;
case 3:strcpy(naziv_datoteke, "prezime.ind");
typedef tprezime slog;
break;
}
int broj_zapisa;
dat.open(naziv_datoteke, ios::in|ios::out|ios::binary);
dat.seekg(0, ios::end);
broj_zapisa=dat.tellg()/sizeof(slog);
// quicksort(0, broj_zapisa-1);
dat.close();
}
I am getting this error:
conflicting declaration 'typedef struct time slog'
I would like to define slog as data type that is stored in file so I can use it later for getting the size of that struct and few other things.

Touching on what Sam mentioned: please have a look at this answer and this page for further information on the topic. Hopefully they help you understand the bigger picture.
To answer your question directly: Defining slog as a data type at runtime is just gonna be messy. More details here.
A quick solution to what you want would be to define a struct slog, which can hold different information for you, like so:
struct slog()
{
int my_val_int = -1;
char* my_val_char = "";
}
Once it's time to return the value, you just check which value is actually set by checking if my_val_int is anything different than your default or if char is not empty.
Mind you, this is a very quick and dirty way of doing it. Please use it only as a starting point to develop your own idea of how to structure the program, so it works in a lean and mean manner! :-)
Goodluck!

Related

Google Kickstart - Wrong answer if cout.clear() is not used

I find this very stupid to ask, but I've been trying a question on Google Kickstart (Round A, 2021).
Now, firstly, I'd like to clarify that I do NOT need help with the question itself, but I'm encountering a weird issue that seems to be compiler-related. This problem only arises on certain compilers.
I am posting the question link, then the question statement if someone does not wish to use the link, then the problem I'm facing along with the code that works and the code that doesn't work.
Question Title: K-Goodness String, Round A (2021)
Question Link: https://codingcompetitions.withgoogle.com/kickstart/round/0000000000436140/000000000068cca3
Problem
Charles defines the goodness score of a string as the number
of indices i such that Si ≠ SN−i+1 where 1≤i≤N/2 (1-indexed). For
example, the string CABABC has a goodness score of 2 since S2 ≠ S5 and
S3 ≠ S4.
Charles gave Ada a string S of length N, consisting of uppercase
letters and asked her to convert it into a string with a goodness
score of K. In one operation, Ada can change any character in the
string to any uppercase letter. Could you help Ada find the minimum
number of operations required to transform the given string into a
string with goodness score equal to K?
Input
The first line of the input gives the number of test cases, T. T
test cases follow.
The first line of each test case contains two integers N and K. The
second line of each test case contains a string S of length N,
consisting of uppercase letters.
Output
For each test case, output one line containing Case #x: y,
where x is the test case number (starting from 1) and y is the minimum
number of operations required to transform the given string S into a
string with goodness score equal to K.
Sample Input:
2
5 1
ABCAA
4 2
ABAA
Sample Output:
Case #1: 0
Case #2: 1
Explanation:
In Sample Case #1, the given string already has a goodness score of 1. Therefore the minimum number of operations required is 0.
In Sample Case #2, one option is to change the character at index 1 to B in order to have a goodness score of 2. Therefore, the minimum number of operations required is 1.
The issue:
The problem is fairly straightforward, however, I seem to be getting a wrong answer in a very specific condition, and this problem only arises on certain compilers, and some compilers give the correct answer for the exact same code and test cases.
The specific test case:
2
96 10
KVSNDVJFYBNRQPKTHPMMTZBHQPZYQHEEEQFQWOJHPHFBFXGFFGXFBFHPHJOWQFQEEEHQYZPQHBZTMMPHTKPQRNBYFFVDNXIX
95 7
CNMYPKORAUTSYETNXAZQZGBFSJJNMOMINYKNTMHTARUMDXAJAXDMURATHMTNKYNIMOMNJJSFBGZQZAXNTEYSTUAROKPKJCD
Expected Output:
Case #1: 6
Case #2: 3
The problem arises when I do NOT use std::cout.clear() at a very specific place in my code. Just printing the value of any random variable also seems to solve this issue, it doesn't necessarily have to be cout.clear() only. I'm pasting the codes below.
**Original Code (Gives incorrect answer):**
//
// main.cpp
// Google Kickstart - Round A (2021)
//
// Created by Harshit Jindal on 10/07/21.
//
#include <iostream>
#define endl "\n"
using namespace std;
int main() {
int num_test_cases;
cin >> num_test_cases;
for (int test_case = 1; test_case <= num_test_cases; test_case++) {
int answer = 0;
int N, K;
cin >> N >> K;
char s[N];
cin >> s;
int current_goodness = 0;
for (int i = 0; i < N/2; i++) {
if (s[i] != s[N-1-i]) { current_goodness++; }
}
answer = abs(current_goodness - K);
cout << "Case #" << test_case << ": " << answer << endl;
}
return 0;
}
Incorrect Result for original code:
Case #1: 6
Case #2: 6
Modified Code (With cout.clear() which gives correct answer):
//
// main.cpp
// Google Kickstart - Round A (2021)
//
// Created by Harshit Jindal on 10/07/21.
//
#include <iostream>
#define endl "\n"
using namespace std;
int main() {
int num_test_cases;
cin >> num_test_cases;
for (int test_case = 1; test_case <= num_test_cases; test_case++) {
int answer = 0;
int N, K;
cin >> N >> K;
char s[N];
cin >> s;
int current_goodness = 0;
for (int i = 0; i < N/2; i++) {
if (s[i] != s[N-1-i]) {
current_goodness++;
}
cout.clear();
}
answer = abs(current_goodness - K);
cout << "Case #" << test_case << ": " << answer << endl;
}
return 0;
}
Correct Result for modified code:
Case #1: 6
Case #2: 3
A few additional details:
This issue is NOT coming up on my local machine, but on Google Kickstart's Judge with C++17 (G++).
Answer for Case #2 should be 3, and NOT 6.
This issue does NOT come up if only the second test case is executed directly, but only if executed AFTER test case #1.
The issue is ONLY resolved if the cout.clear() is placed within the for loop, and nowhere else.
We don't necessarily have to use cout.clear(), any cout statement seems to fix the issue.
I know it's a long question, but given that a problem is only coming up on certain machines, I believe it would require a deep understanding of c++ to be able to understand why this is happening, and hence posting it here. I'm curious to understand the reasoning behind such a thing.
Any help is appreciated.
As pointed out by Paddy, Sam and Igor in the comments, here is the solution as I understand it:
The problem arises because char s[N] is NOT C++ standard, any variable length arrays, for that matter. That might cause a buffer overrun, and will write over memory outside of the array, causing all sorts of weird behaviour.
The best way to avoid these kinds of bugs is to make it logically impossible for them to happen. – Sam Varshavchik
In this case, using string s solved the issue without having to call cout.clear().
Also, using #define endl "\n" might be faster when redirecting output to files, but since we're importing the entire std namespace, any person who does std::cout will get an error because it'll essentially get translated to std::"\n" which does not make sense.

C++ - Pointer to local variable within the function

I know this can look like a rookie question already asked a thousand time. But I searched for the exact answer and I haven't found one...
I'm working on a code that, to sum up, fill an XML with different data.
I'm trying to optimize a part of it. The "naïve" code is the following:
xml << "<Node>";
for(auto& input : object.m_vec)
{
if(input == "Something")
{
xml << input;
}
}
xml << "</Node>";
for(auto& input : object.m_vec)
{
if(input == "SomethingElse")
{
xml << "<OtherNode>";
xml << input;
xml << "</OtherNode>";
break;
}
}
The important thing is, while more than one input fit in <Node></Node>, only one fit in <OtherNode></OtherNode> (explaining the break;) and it may not exist either (explaining the xml << in-between the if statement).
I think I could optimize it such like:
std::vector<std::string>* VecPointer;
xml << "<Node>";
for(auto& input : object.m_vec)
{
if(input == "Something")
{
xml << input;
}
else if(input == "SomethingElse")
{
VecPointer = &input;
}
}
xml << "</Node>";
if(!VecPointer->empty())
{
xml << "<OtherNode>"
<< *VecPointer
<< "</OtherNode>";
}
The point for me here is that there is no extra memory needed and no extra loop. But the pointer to the local variable bothers me. With my beginner's eyes I can't see a case where it can lead to something wrong.
Is this okay? Why? Do you see a better way to do it?
You need to make sure your compairson also looks for an existing value within the VecPointer, since your original second loop only cares about the first value it comes across.
else if(VecPointer && input == "SomethingElse")
Don't look for ->empty(), as that's accessing the pointer and asking whether the pointed to vector is empty. If there's nothing to point to in the first place, you're going to have a bad time at the -> stage of the statement. Instead, if against it, since it's a pointer.
if(VecPointer)
Finally, you're using a Vector to save that one value from m_vec, which from other code I'm assuming is not a vector<vector<string>> but a vector<string> - in the latter case, your VecPointer should be std::string*
std::string* VecPointer = nullptr;
I'm trying to optimize a part of it.
...
Is this okay?
Maybe not! This may already be a poor use of your time. Are you sure that this is what's hurting your performance? Or that there's a performance problem at all?
Remember Don Knuth's old adage: Premature optimization is the root of all evil...
Do you see a better way to do it?
Consider profiling your program to see which parts actually take up the most time.
On an unrelated note, you could use standard library algorithms to simplify your (unoptimized) code. For example:
if (std::ranges::find(std::begin(object.m_vec) std::end(object.m_vec), "SomethingElse"s )
!= std::end(object.m_vec))
{
xml << "<OtherNode>" << whatever << "</OtherNode>";
}

C++ - Using specific character input for 'if' statements

I am, for lack of a better word, an absolute programming novice. And as it stands, I've been flung head first into programming something in two or three languages.
As part of an assignment, we have been tasked with essentially recreating a heads/tails flip, in the form of a random chance game.
The way it works is the player has ten credits to start off with. They are asked to input a wager, and then they are asked heads or tails. Picking either heads or tails sets off a number generator, and depending on the value, they may well end up winning or losing their wager.
I coded a similar version of this using HTML/CSS/JS, and it works. I'll leave a puush link to the file so you can view it yourselves to get an idea of what I'm trying to do: http://puu.sh/bP2V7/2ef63f4a1c.html
I'm trying to do, functionally, the same thing in C++ in the form of a command application. I know the code I'm using works fine, and it compiles without much of a hitch. It's a bit annoying that it closes down rather than resetting to a previous line, but that's a hurdle I'll jump over when I get to it.
I had a look around, and to be honest, whilst a few of the things may well work, I'm admittedly relatively clueless and some of the programmer speak kinda flies over my head.
It's probably because I'm being thrown into it and I'm not used to it yet, but as it stands, I need your help.
My code simply works as follows (simplified to save time):
int main()
{
int points, wager;
points = 10;
output "HEADS OR TAILS?";
if (player has 1 point or more)
{
output "Input wager";
input wager value;
output "Wager is (player input)";
output "Heads or Tails?";
input h or t; //This was what I wanted
if (player selects 'heads') //For sake of simplicity, the code
{ //here will account for both heads
int heads; //and tails.
srand(NULL);
heads = random number 1 and 2;
if (heads = 1)
{
output "HEADS!";
output "You win 'wager'!";
points = points + wager;
}
if (heads = 2)
{
output "TAILS!";
output "You lose 'wager'!";
points = points - wager;
}
}
}
if (player has 0 points)
{
output "GAME OVER";
}
}
What I want to do is have the user input either an 'h' or a 't' to determine whether or not they want heads or tails.
In your programming class, they will have told you what they expect you to use as tools for input and output, eg char inputChar; cin >> inputChar; or similar. Use whatever they told you to use in the style they want you to use, eg
cout << HEADS_OR_TAILS_PROMPT;
char inputChar;
cin >> inputChar;
switch(inputChar) {
case 'h':
{
... // code for the heads case
break;
}
case 't':
{
... // code for the tails case
break;
}
default:
// whatever you want to do if they didn't input a valid option
}
Although, to be honest, asking your professor is going to get you a better answer for what the grader is expecting than asking us is.

Designing a weighted keyword matching string-compare to sort resume docs by relevance

I need to make some design docs- I'm at a loss to decide on data-type and process issues ...i know there are far more experienced designers who can help me find a KISS-simple ADT or template that i haven't been able to find so lets start with requirements:
The main function retrieves resumes and ranks them from MOST to Least based on:
**User-defined keywords** that are assigned an int Value
//the best type seems to be pairing:
template <class udKeyword, class IntValue>
class Pair{
Public: udKeyword one; IntValue two;
}
//note ...a PairList class is also req'd
The ranked_doc_list needs to be massively scalable so I am unsure whether to call a sort when the user requests the ranked_doc_list or if res_docs should insert themselves (and push_back lower-ranked res_docs) as they come in. that approach seems best but also seems like a lot of waste in terms of computation and memory.
I'm starting with a very simple example.
The client is going to enter udKeywod/Value pairs My_client_company will post
"Experienced Bartender needed - please email resume to client#xxxxx.yyy"
assume "Experienced" = 7, "Bartend" = 5, "Bartending" = 5, "Customer Service" = 4, "Diploma" = 3... ...etc. (an enumeration)
I would prefer the resumes come in as .doc files that I can break down by **resume_filename** and build a template for each document as opposed to making it functional as well:
/*FORGIVE MY C++ STL (untested - I'm on a laptop running Win7 that
makes me miss my HP-UX and SParc-Solaris Labs greatly*/
//extract the file name and parse/allocate the text into a CSV array
template <class filename, class CSV_unordered_list>
class doc_data_pull{
public:
string name() = new resdoc.filename;
int wordQty = CSv_unordered_list.get_size();
string csv[];
void getCSVarray{
for(int i=0; i < wordQty; CSV_unordered_list.next(); i++){
csv[i] = CSV_unordered_list.get_string();
}
}
//compare csv array using a strcompare wwith udKeywords and assign a score to name
template <class PairList; class doc_data_pull;>
class ranksResume{
getCSV_matches_and scores(csv[]; name();{
int PLsize = Pairlist.size();
int i=0;
int score[] = 0;
int PLindex = 0;
while (PLindex < Pairlist.size();{
if (csv[i] == Pairlist.udKeyword()** //string-compare is the centerpiece of the logic
score = Pairlist.score //the user-defined keyword matched
i++; Pairlist.next();
PLindex++;}
else{i++; PLindex++;}}//end else and while
//report the score and name() for QC sanshot
cout<< name() /*should be initial filename uploaded to /root */ << scored a << score \n;
//a listype for **ranksResume is also skipped over due to laziness**
#include "udKeyword.h" //for user to define keywords per job posting
#include "intKey.h" //an integer value with a unique identifier to prevent "ties"
#include "pair.h" //keyword, value from user
#include "pairlist.h" //user-defined and created listype Keyword and Relevance metric
#include "filename.h" //extracts the text "filename" or 1st txt line for txt-only resumes
#include "CSVunorderdList.h" //creates a CSV array for str-compare to udKeyword
#include "doc_data_pull.h"//provides CSV for each doc AND the resume-filename
#include <iostream>
#include <string>
#include "ranksResume.h" //WIP
using namespace std;
int main(){//I have almost no recollection of switches in the .cpp so bear w/ me
char input;
cout << "What would you like this bogus document-SEO-based idea of yours to do? <<endl;
cin >> input;
switch(a, b, c, d, e, f, g, h) {
case a : Add a new Keywored
case b : change the value of a Keyword
case c : you have << filename.size() << new resumes. Display all? << ranksResumeList.print()'
Case d : display just the top 10. << ranksResumeList.printTopTen();
case e : delete a resume
case f : favorite a resume
case g : mark this job search complete
case h : exit.}
return 0;
//take benzodiazepenes
}//end main
Anyway that is probably my first pile of object code in a decade. It's partial, probably loaded with bugs and type-missmatch ... but you can prob see where my pseudocode-solution are headed I did search for this a week ago an found very little posts or comments of worth on paired data lists that define the rank of documents (or strings, objects....) based on a robotic selection of keywords and subjective weight to develop "relevance" it's bs but customers really want to sort client documents this way...it's institutionalized SEO corruption but whatever...I'll work on anything for a few bucks.As designers though....I really want to know which algorithms and ADTs you would use to solve this.DONT feel obligated to give answers in C/C++/Java...plus I never touched on how a (php?) function I'd would implement the receipt and likely sorting/indexing of .doc files.

C++ input of type char, output of type int

I am taking my very first C++ class and I am stuck. I would really appreciate some help from you experienced programmers.
The assignment is creating a blackjack-scoring program. Not a very realistic one, but hey. The user inputs how many cards he wants and then the values of each of those cards. The assignment specifies that the inputs should be in type char. So if the user has a 2 card they enter 2, but that 2 is actually char and must be converted to int. Or they would enter "Q" if they have a queen and my program is supposed to convert that Q to ten points for scoring. I cannot figure out what is the right way to do this. The assignment suggests I will use either a switch statement or nested if-else statement, but I am afraid I don't understand switch very well from the book examples.
So here's a tiny bit of my attempts at switch. *points_for_card* is of type char and *number_value* is int.
switch (points_for_card)
{
case '2':
number_value = 2 ;
break;
case '3':
number_value = 3 ;
break;
// ETC
}
So what I am going for here is: if the user enters '3' as a char, it becomes int 3. But maybe this is not how switch works at all.
The thing is, my program compiles and works, but returns weird crazy huge numbers. If I move points_for_card to int instead of char, then the arithmetic works perfectly for whatever numbers I enter, because at that point it's just adding them together.
I hope I explained this ok, will clarify as much as possible if necessary.
it can be something like this code:
if (points_for_card >= '1' && points_for_card <= '9'){
number_value = points_for_card - '0'; // convert to number
}else if (points_for_card == 'Q'){
...
}
A map comes to mind. You can store the scores directly, or you can make one map to look up the card type and other maps to associate other information (like score) to each card. Here's the baby example:
std::map<char, int> scores;
scores['Q'] = 10; scores['A'] = 13; scores['2'] = 2; // etc.
char c;
std::cout << "Please enter a card: ";
std::cin >> c;
std::cout << "Your card has score " << scores[c] << std::endl;
Oftentimes when your heart says "switch", your brain should say "map" :-)
Personnally I'd define an enum ECardType { Card_2, ..., Card_10, Card_Jack, ... }; and have one map be std::map<char, ECardType>, and then other maps from card type to secondary information like scores.
How are you taking inputs into points_for_card ?
Your input should be cin >> points_for_card;
Instead of comparing a character to a character, you can also compare it to the ASCII value of a character.
For example,
char letter = 'A'
if(letter == 65){
cout << "Match";
}
The above code will output "Match!".
Also, your switch statements are perfectly worded. The problem lies elsewhere in your program, so please provide the relevant source.
Another point related to your program but not your problem: How are you dealing with Aces ? You know that they can be counted as either 1 or 11, depending on the player's hand value, right ?