Finding duplicates in Array of structure - qt

I am using QT to search for duplicate entries in a structure.I have a struct as follows:
struct information{
QString fname;
QString lname;
QString gender;
QString age;
QString cod;
};
I have this code here which has bool variable for each variable in the structure and changes the bool value to true if data in the two arrays are the same and checks to see if all the bool values are true and prints out the two lines where duplicates are.
for (int i=0; i<numlines; i+=1){
for (int j=i+1; j<numlines; i+=1){
bool fname = false;
bool lname = false;
bool age = false;
bool cod = false;
bool gender= false;
if (person[i].fname == person[j].fname){
fname = true;
//qDebug() <<fname;
}
if (person[i].lname == person[j].lname){
lname = true;
//qDebug() <<lname;
}
if (person[i].gender == person[j].gender){
gender = true;
//qDebug() <<gender;
}
if (person[i].age == person[j].age){
age = true;
//qDebug() <<age;
}
if (person[i].cod == person[j].cod){
cod = true;
//qDebug() <<cod;
}
if (fname==true && lname==true && gender==true && age==true && cod==true){
//print out where duplicate are.
//duplicates at line i+1 and j+1
}
}
}
When I click my duplicate check button which activates the code it enters the loop once and terminates the program unexpectedly. Any suggestions?

for (int i=0; i<numlines; i+=1){
for (int j=i+1; j<numlines; i+=1){
// ^
Simple problem (probably cut'n'paste error) - you need to increment j, not i.
And, as an aside, you could probably refactor your code to make it a bit simpler since, if any field doesn't match, you can just move to the next, something like (pseudo-code):
for i = 0 to (sz - 2) inclusive:
for j = (i + 1) to (sz - 1) inclusive:
if person[i].fname != person[j].fname: continue
if person[i].lname != person[j].lname: continue
if person[i].age != person[j].age: continue
if person[i].cod != person[j].cod: continue
if person[i].gender != person[j].gender: continue
// they're all equal at this point, log the fact.
This removes the need for those boolean variables.
But, if you do decide to keep the booleans, you can make your code more readable by choosing their names carefully. I tend to prefer booleans to be readable such as customerIsDead or managerHasPsychopathicTendencies. That way, they "flow" easier when reading the code:
if (sameFName && sameLame && sameGender && sameAge && sameCod) {
You should generally never have compare a boolean value with true or false since that just gives you another boolean and, as per reductio ad absurdum, where do you stop?
if ((((x == true) == true) != false) == true) ...

Related

Loop program if user enters wrong input

I just started learning C# and while loops are confusing me. Unlike Java, where I can use a while loop to loop a program if a user entered a invalid input, it's not acting the same way in C#.
using System;
namespace first {
class Program {
static void Main(string[] args) {
Console.WriteLine("Hi! What is your name");
string userName = Console.ReadLine();
Console.WriteLine("oh! you are:" + userName);
Console.WriteLine("let play a game");
string answer="Y";
while (answer == "Y") {
Random random = new Random();
int correntNumber = random.Next(1, 2);
int guess = 0;
Console.WriteLine("Guess a number");
while (guess != correntNumber) {
string userGuess = Console.ReadLine();
//validate input method 1
try {
guess = int.Parse(userGuess);
} catch (Exception e) {
Console.WriteLine("Invalid inout", e);
}
//validate input method 2
//if(!int.TryParse(userGuess, out guess)) {
// Console.WriteLine("invalid input");
//}
if (guess != correntNumber) {
Console.WriteLine("try again!");
}
}
Console.WriteLine("Yes! corrector");
Console.WriteLine("Play again?");
//string answer;
answer = Console.ReadLine().ToUpper();
if(answer == "Y") {
continue;
} else if (answer == "N") {
Console.WriteLine("bye");
return;
} else if (answer != "Y" || answer != "N") {
Console.WriteLine("y or n");
answer = Console.ReadLine().ToUpper();
continue;
}
}
}
}
}
When I enter a value other than y or n, the message appears,Console.WriteLine("Y or n only");, but the game restarts while it shouldn't.
I am sorry this is a simple and rather silly question, but I can't pin point where I am going wrong.
the problem is that after printing to the user "y or n only" message you take the input but you don't actually do anything with it
so the loop just restarts regardless of the input , to fix this issue you could replace the last if part with this code
while(answer != 'Y' && answer != 'N'){
Console.WriteLine("y or n only");
answer = Convert.ToChar(Console.ReadLine().ToUpper());
}
if(answer == 'Y')
{
continue;
}
else if(answer == 'N')
{
Console.WriteLine("goodbye");
return;
}
so after you read the first input answer of him for repeating or no you check if it's a valid input or not and if it's not you keep asking him for "y or n only" till he enters "Y" or "N" and then you process this answer for whether it's a "Y" or "N" in the if part

Function to check whether a binary tree is binary search tree or not?

I attempted writing the following method which tells whether a Binary Tree is Binary Search Tree or not? I pass only half of the test cases. What am I doing wrong?
boolean checkBST(Node root) {
boolean leftflag = false;
boolean rightflag = false;
Node l = root.left;
Node r = root.right;
if(l!=null) {
if(root.data <= l.data) {
leftflag = false;
}
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
if(r != null) {
if(root.data >= r.data) {
rightflag = false;
}
else {
rightflag = true;
checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
I can see a case where your program could return wrongly false.
Imagine you have a tree with 3 branches deep going as follow :
7
/ \
3 8
\ / \
4 6 9
Your program starts up at 7 (root), creates two boolean at false (leftflag and rightflag), checks if left is null. It isn't. It then checks if the data of left <= the data of right. It is.
So you recursively call your function with a new root node left (3 in the example). Again, it creates your two boolean at false initial value, checks if left node is null. It is ! So it skips the whole if, goes directly to your other if before the return.
// The condition here is respected, there is no left node
// But the tree is an actual search tree, you didn't check right node
// Before returning false.
if(leftflag == false)
return false
What i'd do is
if(l != null)
{
if(root.data<=l.data)
{
return false;
}
else
{
// recursive call here
}
}
if(r != null)
{
// Same as left node here
}
so even if your left node is null, the program still checks for the right node. Hope i helped out a little bit !
Your primary mistake is that you ignore the return value of your recursive calls. For instance:
else {
leftflag = true;
checkBST(l);
}
}
if(leftflag == false)
return false;
If checkBST(l) returns false, you ignore it. You never save the value. Thus, your subsequent check for leftflag is utterly ignorant of the subtree's suitability. Semantically, your routine assumes that all subtrees are BSTs -- you set the flag, recur on the subtree, but don't change the flag. Try this logic:
else
leftflag = checkBST(l)
Now, please get comfortable with Boolean expressions. For instance, testing a Boolean value against a Boolean constant is a little wasteful. Instead of
if (flag == false)
Just check directly:
if (!flag)
Checking a pointer for null is similar in most languages:
if (l)
Finally, don't initialize your flags if you're simply going to set them to the same value as the first action.
Now, your code might appear like this:
boolean leftflag = false;
boolean rightflag = false;
if(l) {
if(root.data > l.data) {
leftflag = checkBST(l);
}
}
if(!leftflag)
return false;
if(r) {
if(root.data < r.data) {
rightflag = checkBST(r);
}
}
if(rightflag == false)
return false;
return true;
}
Now it's a little easier to follow the logic flow. Note that you have a basic failure in your base case: a null tree is balanced, but you return false.
Now, if you care to learn more about logic short-circuiting and boolean expressions, you can reduce your routine to something more like this:
return
(!root.left || // Is left subtree a BST?
(root.data > root.left.data &&
checkBST(root.left)))
&&
(!root.right || // Is right subtree a BST?
(root.data > root.right.data &&
checkBST(root.right)))

How to count statements in C ignoring the comments

int Emptylines(FILE *fp);
int Numberofstatements(FILE *fp);
int main() {
FILE *fp = NULL;
FILE *fp1 = NULL;
int n1, n2;
char fname[255], fname1[255];
printf("Enter file name for reading");
fflush(stdin);
scanf("%s", &fname);
fp = fopen(fname, "r");
if (fp == NULL) {
printf("File with name %s couldn't be open", fname);
exit(1);
}
n1 = Emptylines(fp); // this is for empty lines
n2 = Numberofstatements(fp);
printf("Insert file name for writing");
fflush(stdin);
scanf("%s", &fname1);
fp1 = fopen(fname1, "w+");
fprintf(fp1, "The number of empty lines=%d", n1);
fprintf(fp1, "The number of statements=%d", n2);
fclose(fp);
fclose(fp1);
return 0;
}
int Numberofstatements(FILE *fp) {
char line[128];
int nofstatements = 0;
while (fgets(line, sizeof line, fp) != NULL) {
if (strstr(line, "if") != 0)
nofstatements++;
}
return nofstatements;
}
I need to count all statements like if, do, while, break, etc. as well as empty lines and then save the result in a new file. I succeed in counting the empty lines but I have no idea how to count the statements. I tried 2 different ways but both failed.
I also need to ignore comments while reading the code, so if there is a for, while, etc. in the comments it shouldn't be counted.
A very basic answer addressing the fundamental issue (although there are others).
When you call int Numberofstatements(FILE *fp) you already reached the end of file in int Emptylines(FILE *fp); so you must add the statement
rewind(fp);
before trying to parse the file for a second time. Good luck with developing this.
OP asks: "Any ideas ?"
To do properly, suggest reading 1 char at a time. Keep track if you are in 1) on an include line, 2) inside a " " 3) inside a ' ' 4) in a // comment 5) inside a /* comment or 6) just plain code (watch for escape sequences). When in plain code look for the keywords do, while, etc. and all the while count the '\n'.
To do correctly - this is not an easy task - about 10x the code you have posted.
Sample beginning of a state machine.
state = plaincode;
while ((c = getc()) != EOF) {
switch (state) {
slashslash_commnet:
if (c == '\n) state = plaincode;
break;
plaincode:
if (c == '/') {
c2 = getc();
if (c2 == '/') { state = slashslash_commnet; break; }
else if (c2 == '*') { state = slashstar_commnet: break; }
else unget(c2);
else if (c == '\"') {
...

Palindrome Recursion Program

public static boolean palindrome(String input, int i, int j)
{
if (i >= j)
return true;
if (input.charAt(i) == input.charAt(j))
{
i++;
j--;
palindrome(input, i, j);
}
else if (input.charAt(i) != input.charAt(j))
return false;
}
My Java platform (eclipse) won't accept this code as working, due to a "lack of return type." Now I know in proper coding ediquite, it's better to use only one return value, but when it comes to recursion, this is somewhat new to me. How can I go about doing this? If I instantiate a Boolean type at the top of this method, it's creating a new instance of that variable (and instantiating it as null or whatever I set it to) each time the method runs, but if I place it above my constructor, my method won't assign a value to it/can't return it.
Basically, how do I go about modifying my code to have a single return value that Eclipse will accept as always executing? I can do this easily enough with loops, but I'm not sure how to approach the topic with Recursion.
Just for improved readability:
public static boolean palindrome(String input, int i, int j)
{
if (i >= j)
return true;
if (input.charAt(i) != input.charAt(j))
return false;
return palindrome(input, i + 1, j - 1);
}
If we could use C# and Linq (since I don't have Java dev environment here) to reversing a char array:
public static bool palindrome(String input)
{
return input.Equals(new String(input.ToCharArray().Reverse().ToArray()));
}
The issue is that you have no return inside the second if statement. If charAt i and j are equal you never return anything.
Keeping the spirit of your code I'd shorten the whole thing up to be:
public static boolean palindrome(String input, int i, int j)
{
if (i >= j)
{
return true;
}
if (input.charAt(i) == input.charAt(j))
{
return palindrome(input, i + 1, j - 1);
}
return false;
}
You can certainly just do this:
return palindrome(input, i, j);
However it is good practice to have a single return to improve readability. Try this on for size:
boolean isPalindrome = false;
if (i >= j)
isPalindrome = true;
else if (input.charAt(i) == input.charAt(j))
{
i++;
j--;
isPalindrome = palindrome(input, i, j);
}
else if (input.charAt(i) != input.charAt(j))
isPalindrome = false;
return isPalindrome;
}
Have that boolean always instantiated. The key here is to make palindrome's return be stored in that boolean.
The recursive portion comes in at the call to palindrome. It will only finally return the final value after all of the recursive calls, because it only ever determines if its a palindrome when it reaches the end of the recursive cycle.
In the second if block, you don't return anything.
Just change the recursive call so that you return its value:
return palindrome(input, i, j);
Also, incidentally, you don't need to do i++ and j-- in the if block-- you can instead call the palindrome method with i+1 and j-1 instead, and that will have basically the same effect.
public static String palindrome(String input, int i, int j)
{
if (i >= j)
return "-1";
//--------------------------------------------//
if (input.charAt(i) == input.charAt(j))
{
i++;
j--;
//--------------------------------------------//
palindrome(input, i, j);
return "is palindrom";
}
//--------------------------------------------//
else
return "not palindrom";
}
}
//--------------------------------------------//
An other option might be this:
boolean isPalindrome(String s) {
boolean ret = true;
if (s.length() == 1 || s.equals("")) {
return ret;
} else {
char first = s.charAt(0);
char last = s.charAt(s.length() - 1);
if (first != last)
ret = false;
else if (s.length() > 2) {
String partial = s.substring(1, s.length() - 1);
ret = isPalindrome(partial);
}
}
return ret;
}
Probably this answer can help(in Python):
def isPalinr(str1):
if len(str1)<=1:
print('Palindrome')
return
if (str1[0] != str1[-1]):
print ('Not palindrome')
return
else:
return isPalinr(str1[1:len(str1)-1])
This will return None though we can return string in first 'if' clause because program will ultimately stop at that point.

Where to find or duplicate code that produces HttpRequestValidationException

I have some PageMethods (static methods in a page marked with <WebMethod>) defined on some pages and call them using an ajax call. This POST to the server apparently doesn't trigger the ASP.NET code that would raise HttpRequestValidationException if the data sent is deemed possible XSS, so I'd like to duplicate that checking code to run it in my page methods.
Anyone know the details of that code or where I can find it? I looked in the MS AntiXss library, but it only does encoding, not actually checking input, AFAIK.
Edit: Or point me in the direction of code or a library that does some similar checking.
Analyzing the stack trace when a System.Web.HttpRequestValidationException is raised we can find out what code is throwing it.
System.Web.HttpRequestValidationException (0x80004005): A potentially dangerous Request.Form value was detected from the client (IdentifierTextBox="
at System.Web.HttpRequest.ValidateString(String value, String collectionKey, RequestValidationSource requestCollection)
Using Reflector we find that ValidateString is calling: RequestValidator.Current.IsValidRequestString, which in turn calls CrossSiteScriptingValidation.IsDangerousString which is:
internal static bool IsDangerousString(string s, out int matchIndex)
{
matchIndex = 0;
int startIndex = 0;
while (true)
{
int num2 = s.IndexOfAny(startingChars, startIndex);
if (num2 < 0)
{
return false;
}
if (num2 == (s.Length - 1))
{
return false;
}
matchIndex = num2;
char ch = s[num2];
if (ch != '&')
{
if ((ch == '<') && ((IsAtoZ(s[num2 + 1]) || (s[num2 + 1] == '!')) || ((s[num2 + 1] == '/') || (s[num2 + 1] == '?'))))
{
return true;
}
}
else if (s[num2 + 1] == '#')
{
return true;
}
startIndex = num2 + 1;
}
}

Resources