• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Karl2177

Member
I've been thinking about this for hours now, without any real breakthrough, so maybe you guys can help. I'm using Java. I have a two-dimension custom class array, and I want to go through and check that there are no duplicates. I have the equals() method overriden for the custom class. The only solution I've been able to come up with is to have a nested for loop for increasing the position that I am checking and another nested for loop(inside that one) for the equals() method. I feel like I'm overlooking something incredibly simple, because I don't think it should be O(n^4).
 
So uh echoing the working for hours thing, and this is really pissing me off. I have to make changes to a calculator in c. Fine and dandy, that's done. What I then need to do is change the old main to something else, and have the new main ask the user then call to the old main. Problem is, no matter what I do I keep getting errors in the fact that I can't "implicitly call" the function even though I've been doing it the way I normally do.

Code:
int main()
{
....
    printf("Blah blah blah");
    evaluate();
....
}

How the hell is that not a valid function call?

It's probably something really simple, but I've been working and studying on multiple assignments and my brain is fried.
 

jon bones

hot hot hanuman-on-man action
I am surprised that it didn't work for you. I have used this several places in my code (Windows operating system if you must know!). Make sure foo is a UNLONG64 variable though.

This is not to say that once you moved this to a local variable you can display it easily. You have to typecast a pointer to this variable to UCHAR* and then fetch every character and print it. My point was to show how the result of an operation done in an asm block can be transferred to a local variable (which I thought your problem was).

then i probably didnt implement it correctly - i ended up just cutting the asm block into 8 bit chunks and then moving each chunk a character array. thanks again for your help!

just wrapped up figuring out forking children/using pipes. gonna do some self study in python next. really refreshing to do something i'm interested in vs all those years i spent doing finance work.
 
So uh echoing the working for hours thing, and this is really pissing me off. I have to make changes to a calculator in c. Fine and dandy, that's done. What I then need to do is change the old main to something else, and have the new main ask the user then call to the old main. Problem is, no matter what I do I keep getting errors in the fact that I can't "implicitly call" the function even though I've been doing it the way I normally do.

Code:
int main()
{
....
    printf("Blah blah blah");
    evaluate();
....
}

How the hell is that not a valid function call?

It's probably something really simple, but I've been working and studying on multiple assignments and my brain is fried.

You don't give a lot of info here. What is evaluate (), where is it declared and how is it declared? What is the full compile error?
 

Slavik81

Member
I've been thinking about this for hours now, without any real breakthrough, so maybe you guys can help. I'm using Java. I have a two-dimension custom class array, and I want to go through and check that there are no duplicates. I have the equals() method overriden for the custom class. The only solution I've been able to come up with is to have a nested for loop for increasing the position that I am checking and another nested for loop(inside that one) for the equals() method. I feel like I'm overlooking something incredibly simple, because I don't think it should be O(n^4).

Yes, you can do better.
For each value in the array:
Look up if you've already inserted it into a map - O(log n)
Insert it into the map - O(log n)

2*(log n) is still O(log n). Thus, I think the overall is O(n*log n).

Though, in that, n is the total number of array elements. n=w*h, where w is the width of the 2D array and h is the height. Your n^4 is really just n^2 if n were the number of elements, rather than the side length of a square array.

Basically: sort it and duplicates will be side-by-side so you can find them in linear time. Sorting can be done in O(n*log n).

Code:
int main()
{
....
    printf("Blah blah blah");
    evaluate();
....
}

How the hell is that not a valid function call?

I'm going to guess that you don't have the function declared before you used it. Does your code look like this?

Code:
void evaluate();

int main()
{
....
    printf("Blah blah blah");
    evaluate();
....
}
 

mike23

Member
Yes, you can do better.
For each value in the array:
Look up if you've already inserted it into a map - O(log n)
Insert it into the map - O(log n)

2*(log n) is still O(log n). Thus, I think the overall is O(n*log n).

Though, in that, n is the total number of array elements. n=w*h, where w is the width of the 2D array and h is the height. Your n^4 is really just n^2 if n were the number of elements, rather than the side length of a square array.

Basically: sort it and duplicates will be side-by-side so you can find them in linear time. Sorting can be done in O(n*log n).

You could also use a HashMap which would make the algorithm linear time.
 

Karl2177

Member
Yes, you can do better.
For each value in the array:
Look up if you've already inserted it into a map - O(log n)
Insert it into the map - O(log n)

2*(log n) is still O(log n). Thus, I think the overall is O(n*log n).

Though, in that, n is the total number of array elements. n=w*h, where w is the width of the 2D array and h is the height. Your n^4 is really just n^2 if n were the number of elements, rather than the side length of a square array.

Basically: sort it and duplicates will be side-by-side so you can find them in linear time. Sorting can be done in O(n*log n).
Ah thanks. I completely forgot about sorting. And I feel silly now for counting it side x side x side x side for n^4...

You could also use a HashMap which would make the algorithm linear time.
If my class had gone over that yet, I might have considered that. ;)
 

Haly

One day I realized that sadness is just another word for not enough coffee.
So I stumbled onto this paper titled Do We Really Need Quaternions?, which led me to a thread called Why Diana Gruber's wrong about Quats, and after about 5 pages of bickering, I got bored, but I'm still kind of curious as to whether people use/refuse quaternions and why.

I learned about Quaternions a year or two back and I feel comfortable enough with them that I'd use Quaternions when given the opportunity, since they're compact and easy on the eyes, they avoid the dreaded Gimbal lock (something I've never actually encountered), and they SLERP nicely (I usually stick with LERP because it's easier to implement). I have to admit I don't understand them very well, and that after implementing my Quaternion class (or using built in ones), I just treat them like a black box. Since that thread is over 10 years old, I'm wondering if 3D programming has found a simple answer to the question of why/when to use Quaternions.
 

Slavik81

Member
This is not really answering your question, but I found the history of quaternions fascinating. That they existed as a mostly-forgotten mathematical curiosity for a decades is amazing.

William_Rowan_Hamilton_Plaque_-_geograph.org.uk_-_347941.jpg


Here as he walked by
on the 16th of October 1843
Sir William Rowan Hamilton
in a flash of genius discovered
the fundamental formula for
quaternion multiplication
i^2 = j^2 = k^2 = ijk = −1
& cut it on a stone of this bridge
(more)
 
Alright I am legitimately stumped with this and it's bothering me. It's another modifying string in c problem...

What I need to do is take in a string, pass it to a function. The function takes the string and takes any part where the string = '\t' and replaces it with spaces, using tabsize - (offset % tabsize), and then returns the string pointer to output in main.

No matter what I do, I just can't get it to work. any hints? Cause this problem has been haunting me for a week now, and I know there's something I'm missing. I can get it to work where it reads each individual character, but not with a string for some reason....
 
well, without code it's hard to judge what's wrong
do you return the new string or is it part of the function parameters?,..

I scrapped most of what I had but this is the idea:

Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char* detab(char* s, int n);

int main(void)
{
    int tab;
    char str[2000];		//declaring char array for max size
    
    printf("Enter a string: ");
    fgets(str, sizeof(str), stdin);
    
    printf("Enter an integer to adjust TAB by: ");
    scanf("%i", &tab);

    detab(str, tab);
    
    //printf("%s", str);
    return 0;
}

//This function takes a pointer to a string as an argument
//and reads each value of the array the pointer points to
//and replaces each '\t' with the corresponding amount of spaces

char* detab(char* s, int n)
{
//this is where my issue is. I can't figure out how to manipulate to adjust where s = '\t' with appropriate spaces

return s.
}

trying to copy the string character by character using a temp array and a loop where temp a[index] = s[index] but that's not right.
 
I'm having an extraordinary hard time trying to figure out how to make a program in java that will take a starting number and a ending number from the main method, then check those numbers and every number in between for prime numbers. When it finds prime numbers it prints them out.

I've been trying to do this for an hour at this point with no progress in the slightest. How is this done? I'll take any hints I can get, I dont necessarily want you to write the code for me, I am just so frustrated with this.
 

Slavik81

Member
I'm having an extraordinary hard time trying to figure out how to make a program in java that will take a starting number and a ending number from the main method, then check those numbers and every number in between for prime numbers. When it finds prime numbers it prints them out.

I've been trying to do this for an hour at this point with no progress in the slightest. How is this done? I'll take any hints I can get, I dont necessarily want you to write the code for me, I am just so frustrated with this.

What's the range of the starting and ending numbers?
 
What's the range of the starting and ending numbers?

it could be any number you want to put in. It could be from 1 to 100, 34 to 58, anything.

I have some code that will tell if the start number is prime or not but I cant seem to figure out the rest of the code that will fill in the numbers between the starting number and the ending number.


Code:
public static void IsPrime(int startNum, boolean isitPrime)
	{
		if (startNum < 2 || (startNum % 2 == 0))
            isitPrime = false;
        if (startNum == 2) 
        	isitPrime = true;
        
        if (isitPrime)
            for (int i=3; i<=(startNum/2); i+=2)
                if (startNum % i == 0)
                {
                    isitPrime = false;
                    break;
                }
        if (isitPrime == true) 
            System.out.println(startNum + " is a prime number.");
            else
            System.out.println(startNum + " is NOT a prime number.");
		}
 

Slavik81

Member
it could be any number you want to put in. It could be from 1 to 100, 34 to 58, anything.

I ask because finding the primes between 600851475143 and 600851476143 requires a rather different strategy than finding the primes between 0 and 1000.

Anyways, what you probably want is a loop that uses the prime-checking function you created. I'm a little confused as to why you're passing in a boolean, though. Shouldn't it be the return value?

trying to copy the string character by character using a temp array and a loop where temp a[index] = s[index] but that's not right.

You need two indexes. One for the original array and one for the temporary array. Also, the temporary array needs to be big enough to fit the entire final result in it (unless you do a lot of shuffling for each replacement).
 
You need two indexes. One for the original array and one for the temporary array. Also, the temporary array needs to be big enough to fit the entire final result in it (unless you do a lot of shuffling for each replacement).

Yeah. I have a char string set to the size of s x tabsize.

My problem is trying to go from copying string s from the input, with '\t' in it to the string that will take '\t' and place the appropriate spaces, and then continue on until it encounters either another '\t' or '\0'.

This problem is really frustrating me because I know there's probably a simple way to do it but it's just not clicking.
 
I ask because finding the primes between 600851475143 and 600851476143 requires a rather different strategy than finding the primes between 0 and 1000.

Anyways, what you probably want is a loop that uses the prime-checking function you created. I'm a little confused as to why you're passing in a boolean, though. Shouldn't it be the return value?

I don't think numbers above 100 are going to be checked. Yes, the program should be returning all of the prime numbers between and including the two numbers that are input into the program. So im not sure why I used boolean. I'm gonna rewrite it again and see if I get anywhere.
 

Slavik81

Member
I don't think numbers above 100 are going to be checked. Yes, the program should be returning all of the prime numbers between and including the two numbers that are input into the program. So im not sure why I used boolean. I'm gonna rewrite it again and see if I get anywhere.

The fact that you wrote is isPrime function that gives a boolean result for a single number is great, though! Programming is all about breaking big problems into smaller problems.

You can answer "Is number x prime?" using that function, so all you need to do is ask it that question for each number you're interested in.

Yeah. I have a char string set to the size of s x tabsize.

My problem is trying to go from copying string s from the input, with '\t' in it to the string that will take '\t' and place the appropriate spaces, and then continue on until it encounters either another '\t' or '\0'.

This problem is really frustrating me because I know there's probably a simple way to do it but it's just not clicking.

What I mean is that this code is wrong:
Code:
a[index] = s[index]
index++;

You want:
Code:
if(!insertingExtraChars)
{
   a[aIndex] = s[sIndex];
   aIndex++;
   sIndex++;
} else
{
// insert the extra characters here, and update the indexes appropriately
}

When you insert extra characters into one of the arrays, you'll want to increment one of the indexes extra times. When you're doing the copy, the two index values you need will only be the same until you hit the first tab.
 
I'm still clueless after writing it twice. I dont know how I would do this if I shouldnt use booleans. Heres what I have.
Code:
import java.io.*;
import java.util.Scanner;
public class primes 
{
	public static void main(String[] args) 
	{
		System.out.println("This program will take two numbers from you and produce" +
				" all of the prime numbers between them");
		boolean isitPrime = true;
		int startNum = 0, endNum = 1, number;
		startNum = getStart(startNum);
		endNum = getEnd(endNum);
		checkPrime(startNum, endNum,isitPrime);
	}//end main
	public static int getStart(int startNum)
	{
		Scanner input;
		input = new Scanner(System.in);
		
		System.out.println("Please enter the number you want to start with.");
		startNum = input.nextInt();
		return startNum;
	}//end getStart
	public static int getEnd(int endNum)
	{	
		Scanner input;
		input = new Scanner(System.in);
		
		System.out.println("Please enter the number you want to end with.");
		endNum = input.nextInt();
		return endNum;
	}//end getEnds
	public static void checkPrime(int startNum, int endNum, boolean isitPrime)
	{
		for  (;startNum <= endNum; startNum++)
		{
			if (startNum < 2 || (startNum % 2 == 0))
	            isitPrime = false;
	        if (startNum == 2) 
	        	isitPrime = true;
	        
	        if (isitPrime)
	            for (int i=3; i<=(startNum/2); i+=2)
	                if (startNum % i == 0)
	                {
	                    isitPrime = false;
	                    break;
	                }
	        if (isitPrime == true) 
	            System.out.println(startNum + " is a prime number.");
	        else
	            System.out.println(" ");
	}
}}
 
What I mean is that this code is wrong:
Code:
a[index] = s[index]
index++;

You want:
Code:
if(!insertingExtraChars)
{
   a[aIndex] = s[sIndex];
   aIndex++;
   sIndex++;
} else
{
// insert the extra characters here, and update the indexes appropriately
}

When you insert extra characters into one of the arrays, you'll want to increment one of the indexes extra times. When you're doing the copy, the two index values you need will only be the same until you hit the first tab.

so:

Code:
int i;
    int b, c;
    int ai = 0, bi = 0;
    char str1[(sizeof(s)*n)];
    
    for(i = 0; i < sizeof(s); i++)
    {
        if(s[i] != '\t')
            str1[ai++] = s[bi++];
        else
        {
            b = n - (c % n);//finding appropriate spaces to replace tab
            //need to loop through to to add appropriate spaces to str1
        }
    }
            
        
    for(i = 0; i < sizeof(str1); i++)
        s[i] = str1[i];
    
    return s;

correct? Sorry if being thick, I've been up almost 24 hours working on other projects and this one seems to be making my head spin.
 

Slavik81

Member
I haven't looked through it all, but one thing that stands out to me is that when you pass an array into a function, it degenerates into a pointer.

sizeof(str)==sizeof(char[2000])=2000
sizeof(s)==sizeof(char*)=probably 4.

Thus, sizeof(str1) is probably 4n when you meant it to be 2000n. And your loops will exit way early.
 
I know. I picked up on that quickly and fixed it early on.


I got it to work, but now my issue is a bunch of dumb characters getting thrown to the end of the string.

Code:
  int i;
    int a, b, c;
    int ai = 0;
    char str1[(strlen(s) * n)];
    
    printf("%s", s);
    
    for(i = 0; i < strlen(s); i++)
    {
        a = s[i];
        if(a != '\t')
            str1[ai++] = a;
        else if(a == '\t')
        {
            b = n - (c % n);
            for(c = 0; c < b; c++)
                str1[ai++] = ' ';
        }
        else
        {
            a = '\0';
            str1[a++] = a;
        }
        
    }
            
    for(i = 0; i < strlen(str1); i++)
        s[i] = str1[i];

VUdIJ.png

Which only happens occasionally...

Occasionally being where n >= 10. Huh.
 

Slavik81

Member
Given that you're using variable-length arrays, you must be using c99. You don't have to put your variables at the start of the function, and it will make it much clearer if you do not.

Note that you're using c before you give it a value. You're also using 'a' as an index instead of 'ai' in the else.

Less seriously, a, b and c are unnecessary. And you should not be using strlen in your loop conditional, since it is O(n) and thus makes your loop O(n^2) unless the compiler is smart enough to optimize it away.

Finally, if you have trailing garbage after your string when you print it, that probably means that it is not null terminated. Remember that strlen does not include the null terminator.
 
Yep, caught that too. Damn the less sleep I have the sloppier I get...

and setting c = 0 fixed it.

Less seriously, a, b and c are unnecessary. And you should not be using strlen in your loop conditional, since it is O(n) and thus makes your loop O(n^2) unless the compiler is smart enough to optimize it away.

I understand time complexities a bit (had an overview), so obviously O(n^2) is terrible. What should I use instead of strlen? That is something I haven't figured out.

Note this is for a c and unix systemsclass, and we haven't done anything dealing with Big-O yet, so I'm not too worried about it for the time being.
 

Slavik81

Member
I understand time complexities a bit (had an overview), so obviously O(n^2) is terrible. What should I use instead?

Note this is for a c and unix class, and we haven't done anything dealing with Big-O so I'm not too worried about it for the time being.
strlen advances through the string, checking each character in the string to see if it's null. If you put that in the conditional of your for loop as you iterate over the string, it will do that for each iteration of your loop

Since the string's length doesn't change, just calculate it before starting the loop and use that.
 
strlen advances through the string, checking each character in the string to see if it's null. If you put that in the conditional of your for loop as you iterate over the string, it will do that for each iteration of your loop

Since the string's length doesn't change, just calculate it before starting the loop and use that.

Got it. So:

x = (unsigned)strlen(s);

before the first for loop and setting the limit to x.

and

x = (unsigned)(strlen(str1) + 1);

before the second for loop (the one transferring the contents to string s) and setting the limit to x.

That'll set each loop to O(n) now.

Or am I still running into the issue of strlen iterating through the string and adding more time to it?

Thanks for the help.
 

Slavik81

Member
That should do it.

Honestly, it's not that important given the program you're working on. I doubt you'd face any performance issues in that code, even with 2000 characters. And the compiler might even be smart enough to do it for you. But the idea is worth understanding.
 
I'm still clueless after writing it twice. I dont know how I would do this if I shouldnt use booleans. Heres what I have.

I haven't coded in Java in a while but what exactly is going wrong here?

And just one thing you will need to do is to close your Scanner objects so input.close() needs to be put in your code after you are finished with it. And why are you even using classes just to get a number from the keyboard? It could easily be put in your main. And another thing, why make 2 instances of the scanner? The only reason you would need to do that is if the datatype was different.

Code:
import java.util.*;
public class test {
	public static void main (String[] args){
		Scanner scn = new Scanner(System.in);
		System.out.println("Enter a number");
		int a = scn.nextInt();
		System.out.println("Enter another number");
		int b = scn.nextInt();
		scn.close();
		System.out.println("Sum = " + (a+b));
	}
}
That should work fine. (scanner wise) Between I outputted a sum just as a test.
 
I haven't coded in Java in a while but what exactly is going wrong here?

And just one thing you will need to do is to close your Scanner objects so input.close() needs to be put in your code after you are finished with it. And why are you even using classes just to get a number from the keyboard? It could easily be put in your main. And another thing, why make 2 instances of the scanner? The only reason you would need to do that is if the datatype was different.

Code:
import java.util.*;
public class test {
	public static void main (String[] args){
		Scanner scn = new Scanner(System.in);
		System.out.println("Enter a number");
		int a = scn.nextInt();
		System.out.println("Enter another number");
		int b = scn.nextInt();
		scn.close();
		System.out.println("Sum = " + (a+b));
	}
}
That should work fine. (scanner wise) Between I outputted a sum just as a test.

I rewrote it again, this time without methods just to understand the logic and this is what I am at.
Code:
import java.io.*;
import java.util.Scanner;
import java.lang.Math;
public class thirdprime
{
	public static void main(String[] args) 
	{
		int start, end, count;
		boolean prime = true;
		Scanner input = new Scanner(System.in);
		System.out.println("Please enter the number you want to start at.");
		start = input.nextInt();
		System.out.println("Please enter the number you want to end with.");
		end = input.nextInt();
				
				while (start <= end);
				for (count = start; count <= end; count++)
				{
					if (start < 2 || (start % 2 == 0))
						prime = false;
					if (start == 2);
						prime = true;
						
					if (prime)
						for (int i=2; i<=Math.sqrt(start); i++)
						if (start % i == 0)
		                {
		                    prime = false;
		                    break;
		                }
				  if (prime == true) 
					  System.out.println(count);
				}
				

	}

}

Right now, with this code the problem is it is not moving into the while loop. I dont know why, but I think I may have fixed my problem(or maybe im just tired).
 
That should do it.

Honestly, it's not that important given the program you're working on. I doubt you'd face any performance issues in that code, even with 2000 characters. And the compiler might even be smart enough to do it for you. But the idea is worth understanding.

Gotcha. Thanks for the help.
 
Well, I guess I dont understand this program at all. It takes a starting number and ending number, then it will calculate all of the prime numbers between those two. I'm not quite sure what I am doing wrong, but here is code I wrote at the end of my 3 hours:

Code:
import java.io.*;
import java.util.Scanner;
import java.lang.Math;
public class thirdprime
{
	public static void main(String[] args) 
	{
		int start, end;
		int count = 1;
		boolean prime = true;
		Scanner input = new Scanner(System.in);
		System.out.println("Please enter the number you want to start at.");
		start = input.nextInt();
		System.out.println("Please enter the number you want to end with.");
		end = input.nextInt();
	isitprime(start,end,count,prime);
	}
	
	
	
	public static void isitprime(int start,int end,int count, boolean prime)
	{
			while (start <= end);
				for (count = 1; start <= end; count++)
				{
					if (start < 2 || (start % 2 == 0))
						prime = false;
					if (start == 2);
						prime = true;
						
					if (prime)
						for (int i=2; i<=Math.sqrt(start); i++)
						if (start % i == 0)
		                {
		                    prime = false;
		                    break;
		                }
				  if (prime == true) 
					  System.out.println(start);
				}
				
	}

}

I believe this code is supposed to take the first number and check if it is prime, then add one to the number and repeat until it gets to the ending number. I have no idea where to go from here. I've stared at this long enough for right now so if anyone could help me out it would be much appreciated!
 

Slavik81

Member
MutantCyborg, I still don't understand why you're passing a boolean into isitprime. If I had to guess, you do not understand the concepts of local variables or return values.

You really should seek help in person from your teacher or from a TA, because those are fundamental to programming in almost every language I know of.

Perhaps by seeing properly structured code solving a similar problem, you will understand some of the mistakes you're making.

Code:
public static void main(String[] args)
{
   for(int i=0; i<10; i++)
   {
      if(isInFibonacciSequence(i))
      {
         System.out.println("The number " + i + " is in the fibonacci sequence.");
      }
      else
      {
         System.out.println("The number " + i + " is NOT in the fibonacci sequence.");
      }
   }
}

   
public static boolean isInFibonacciSequence(int number)
{
   if(number == 1) 
      return true;

   int first = 1;
   int second = 1;
   while (number > second)
   {
      int nextNumber = first + second;
      if(number == nextNumber)
         return true;
         
      first = second;
      second = nextNumber;
   }
   
   return false;
}

I'm really a C++ guy, so there might be minor syntax errors, but it conveys the idea.
 

Slavik81

Member
You could also use a HashMap which would make the algorithm linear time.

I was curious as to how this fared in practice. My apologies for the poorly factored code.

Code:
#include <QtCore/QHash>
#include <QtCore/QMap>
#include <QtCore/QElapsedTimer>
#include <algorithm>
#include <vector>
#include <cstdlib>
#include <ctime>

namespace
{
    const int VECTOR_SIZE = 1e7;
}

int main()
{
    int seed = std::time(NULL);
    std::srand(seed);
    qDebug("seed: %d, rand_max: %d", seed, RAND_MAX);

    QElapsedTimer timer;
    timer.start();
    qDebug("Starting data generation");

    std::vector<int> v;
    v.resize(VECTOR_SIZE);
    std::generate(v.begin(), v.end(), std::rand);

    qDebug("Finished data generation in %lldms", timer.restart());

    quint64 duplicateCount = 0;

    qDebug("Starting hashing");
    QHash<int,bool> hash;
    for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        bool& duplicate = hash[*it];
        duplicateCount += duplicate;
        duplicate = true;
    }

    qDebug("Finished hashing in %lldms", timer.restart());
    qDebug("Found %lld duplicates", duplicateCount);

    duplicateCount = 0;
    qDebug("Starting mapping");
    QMap<int,bool> map;
    for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        bool& duplicate = map[*it];
        duplicateCount += duplicate;
        duplicate = true;
    }
    qDebug("Finished mapping in %lldms", timer.restart());
    qDebug("Found %lld duplicates", duplicateCount);

    duplicateCount = 0;
    qDebug("Starting array brute-force");

    std::vector<bool> array(RAND_MAX+1, false);
    for(std::vector<int>::iterator it = v.begin(); it != v.end(); ++it)
    {
        int value = *it;
        if(array[value])
        {
            duplicateCount += 1;
        }
        array[value] = true;
    }

    qDebug("Finished array brute-force in %lldms", timer.restart());
    qDebug("Found %lld duplicates", duplicateCount);

    duplicateCount = 0;
    qDebug("Starting sort and sweep");
    std::sort(v.begin(), v.end());

    for(std::vector<int>::iterator it = v.begin(), endIt = --v.end();
        it != endIt;)
    {
        int current = *it;
        int next = *(++it);
        duplicateCount += (current == next);
    }
    qDebug("Finished sort and sweep in %lldms", timer.restart());
    qDebug("Found %lld duplicates", duplicateCount);
}
Output:
Code:
seed: 1351239341, rand_max: 32767
Starting data generation
Finished data generation in 265ms
Starting hashing
Finished hashing in 249ms
Found 9967232 duplicates
Starting mapping
Finished mapping in 2612ms
Found 9967232 duplicates
Starting array brute-force
Finished array brute-force in 346ms
Found 9967232 duplicates
Starting sort and sweep
Finished sort and sweep in 934ms
Found 9967232 duplicates
 
MutantCyborg, I still don't understand why you're passing a boolean into isitprime. If I had to guess, you do not understand the concepts of local variables or return values.

You really should seek help in person from your teacher or from a TA, because those are fundamental to programming in almost every language I know of.

Perhaps by seeing properly structured code solving a similar problem, you will understand some of the mistakes you're making.


I'm really a C++ guy, so there might be minor syntax errors, but it conveys the idea.

Thanks for the help all night. I'm gonna see the professor today after class to get down what I dont seem to understand.
 
Well, I guess I dont understand this program at all. It takes a starting number and ending number, then it will calculate all of the prime numbers between those two. I'm not quite sure what I am doing wrong, but here is code I wrote at the end of my 3 hours:



I believe this code is supposed to take the first number and check if it is prime, then add one to the number and repeat until it gets to the ending number. I have no idea where to go from here. I've stared at this long enough for right now so if anyone could help me out it would be much appreciated!

1) Again its extremely important that you close your scanner.
2) The count variable that you have in your main class is not needed there. Its pretty much a throw away variable and can be made in your isitprime class in the for loop. Like this: for(int count =1;count<=end;count++); Passing that would be kind of a waste.
3) You absolutely don't need that boolean value.
4) I looked at your program a little closer in Eclipse and I suspect that its not looping because of this piece of code in your isitprime method: while (start <= end); You put a semicolon there but you need brackets. Hopefully after fixing that your program should at least be displaying numbers and it would therefore be easier to debug.
 

Minamu

Member
This is the closest thread to it I suppose. I'm joining a C# course on Tuesday and I'd like some online resources for newbies :) Where should I go?
 

Zajora

Member
Don't mean to hijack your question, MutantCyborg, but I'm starting to learn Java myself and thought I'd give it a try too. Also, is it just me or does Slavik seem to know everything? :p

Code:
import java.util.*;

public class Primes 
{
	static Primes primy;

	public static void main(String[] args)
	{
		primy = new Primes();
		primy.goTime();
	}
	public void goTime()
	{
		ArrayList<Integer> primes = new ArrayList<Integer>();
		Scanner scanny = new Scanner(System.in);
		System.out.print("Enter the starting and ending numbers you wish to find primes between: ");
		int start = scanny.nextInt();
		int end = scanny.nextInt();
		scanny.close();
		
		for (int i = start; i < end; i++) 
		{
			if (primy.isPrime(i)) primes.add(i);
		}
		System.out.println(primes);
	}
	
	public boolean isPrime(int num)
	{
		boolean primed = true;
		for (int i = 2; i < num-1; i++) 
		{
			if (num % i == 0) primed = false;
		}
		return primed;
	}
}

Does it matter that I made the primy object static so it could be referenced from both main and goTime? Is there a better way to do that?

Any constructive criticism would be much appreciated!

(For example, I didn't know before that scanners had to be closed for gc)
 
Don't mean to hijack your question, MutantCyborg, but I'm starting to learn Java myself and thought I'd give it a try too. Also, is it just me or does Slavik seem to know everything? :p

Does it matter that I made the primy object static so it could be referenced from both main and goTime? Is there a better way to do that?

Any constructive criticism would be much appreciated!

(For example, I didn't know before that scanners had to be closed for gc)

If your point was just to mess with working with static then it looks fine to me. (But I'm not the best with that so maybe someone could shed more light on it).

The only thing that I would say you need to fix is your for loop in goTime. From: for (int i = start; i < end; i++) to for (int i = start; i <= end; i++). Because if I put the integers 1 and 7 in there then your original for loop is saying not to check the 7 and the code would output [1, 2, 3, 5] but 7 should be included since its a prime.
 

FillerB

Member
Somebody correct me if I'm wrong (been a LONG time since I used Java) but doesn't static means exactly diddily-squat in this context. You're making a variable (primy) static which is only used by one instance of Primes-class as your entire program is in that class. While making a variable static in a class it means that all instances of that class share the same variable instead of making a specific one.
 

OceanBlue

Member
Edit: dabig2 has a much better and technically correct explanation than I do. You should probably just read his, lol. I think I understand things a bit better after reading it too.

Don't mean to hijack your question, MutantCyborg, but I'm starting to learn Java myself and thought I'd give it a try too. Also, is it just me or does Slavik seem to know everything? :p

Code:
code

Does it matter that I made the primy object static so it could be referenced from both main and goTime? Is there a better way to do that?

Any constructive criticism would be much appreciated!

(For example, I didn't know before that scanners had to be closed for gc)

I'm relatively new to this as well and I don't really know how everything works yet, but to me, there's no reason for you to have a static variable defined in the class.

Basically, what your code does is use the static main method to initialize an instance of Primes. At that point, you can manipulate the Primes object however you want. Since the goTime and isPrime methods belong to the Primes object, you don't need to do anything special to reference primy like creating a static variable (If you need a method to reference the object it belongs to, the this keyword works).

Also, if you're trying to use other methods in the same object, you don't need to indicate the object they belong to. For example, primy.isPrime(i) can be shortened to isPrime(i). In that case, what's happening is that, inside your main method, the object primy that you initialized calls the member method goTime. You can think of goTime as running inside the object primy. Since isPrime is also in the same object, you can reference it without needing to specify the object it belongs to.

I'm not sure my explanation is correct since, as I said, I'm not exactly sure how everything works yet, but that's my understanding of it.
 

dabig2

Member
Does it matter that I made the primy object static so it could be referenced from both main and goTime? Is there a better way to do that?

Any constructive criticism would be much appreciated!

(For example, I didn't know before that scanners had to be closed for gc)

There's no real reason to declare Primes as static. I mean, it won't destroy your program if you do, but in general that's not what you do.

Here's the code without using static variables (bolded is what I changed):

Code:
import java.util.*;

public class Primes {
	[B]Primes primy;
[/B]
	public static void main(String[] args)
	{
		[B]Primes primy = new Primes();[/B]
		primy.goTime();
	}


	public void goTime()
	{
		ArrayList<Integer> primes = new ArrayList<Integer>();
		Scanner scanny = new Scanner(System.in);
		System.out.print("Enter the starting and ending numbers you wish to find primes between: ");
		int start = scanny.nextInt();
		int end = scanny.nextInt();
		scanny.close();

		for (int i = start; i < end; i++) 
		{
			[B]if (isPrime(i))[/B] primes.add(i);
		}
		System.out.println(primes);
	}

	public boolean isPrime(int num)
	{
		boolean primed = true;
		for (int i = 2; i < num-1; i++) 
		{
			if (num % i == 0) primed = false;
		}
		return primed;
	}
}

You see, isPrime and goTime() are methods of your Prime class. When you create an instance variable and call those methods from that instance variable, java does something behind the scenes: it passes an implicit reference of that instance variable to those methods.

For example, primy.goTime() is actually handled behind the scenes like this:
Code:
Primes.goTime(this = primes);

Looks like a static call? That's because it technically is. Java passes an implicit parameter of your instance variable to that method. This is huge because notice how goTime calls isPrime in the code above now. Because isPrime is another method of Primes and because goTime contains a reference to your primes variable, when goTime calls isPrime it passes that implicit parameter to isPrime. Again, here's what's really happening behind the scenes:

Code:
//code snippet for goTime()
for (int i = start; i < end; i++) 
		{
			if (Primes.isPrime(i, this)) primes.add(i);
		}

So instance methods in java actually always have 1 extra instance variable in them. They all accept an implicit parameter that you don't see. This is why you don't necessarily need to declare a variable static like you did. Of course there are a myriad of circumstances that will require you to make static variables and/or static methods, but that's for another time!
 

Zajora

Member
I think what I did was that I imagined goTime as being a static method like main, which was why I was thinking I had to use the instance of Primes in order to call isPrime(i). Silliness :p

I hadn't heard of the implicit parameter of the instance being passed to methods though. Thanks for the info. :eek:

That parameter must be how you can reference the instance that called the method by using "this" within the method, then?
 

usea

Member
This is the closest thread to it I suppose. I'm joining a C# course on Tuesday and I'd like some online resources for newbies :) Where should I go?
Do you know how to program? In other words, are you a newbie to C# or to programming in general?
 

usea

Member
I think what I did was that I imagined goTime as being a static method like main, which was why I was thinking I had to use the instance of Primes in order to call isPrime(i). Silliness :p

I hadn't heard of the implicit parameter of the instance being passed to methods though. Thanks for the info. :eek:

That parameter must be how you can reference the instance that called the method by using "this" within the method, then?
Yes. "this" means "the object that this method was called on." Non-static methods belong to an object, must be called on an object, and "this" inside the method refers to that object. The same rules apply for a non-static class member variable.

Static on a class variable or method means it belongs to the whole class, not just an instance of the class.
 

Zajora

Member
Yes. "this" means "the object that this method was called on." Non-static methods belong to an object, must be called on an object, and "this" inside the method refers to that object. The same rules apply for a non-static class member variable.

Static on a class variable or method means it belongs to the whole class, not just an instance of the class.

I know, I had just never heard that the reason "this" works is because it's actually getting passed to the method as a parameter you can't see. That's actually not even mentioned on Oracle's java tutorial page about "this". (Or at least if it is, I didn't see it ;p)
 

Thraktor

Member
Thought you guys might be interested in a thread I set up for Parallella. For anyone who hasn't heard of it, it's a $99 Raspberry Pi-style board with a 16-core processor, and it's currently on Kickstarter ($695k of $750k currently funded with 26 hours to go, should just about reach the target at current pace). Really interesting tech behind it, and it's perfect for folks (like me) who want something relatively cheap to learn parallel programming on.
 
Top Bottom