I'm working on euler problem 14 (http://projecteuler.net/problem=14). I've tried to tackle it by having a method which runs through the collatz equations, and returns the number of steps taken. If it's higher then the current record it overwrites it, otherwise it moves on to the next integer. It was giving stack overflow errors so I added the system.out.println messages to try and identify where it was stalling, and currently it dies whenever it reaches 5200~, I'm confused as to why, because as far as i can tell no values encountered at this point should go over the int limit, and the error persisted even if i changed "numberStorage" from int to long.
Here is my current code:
/**
* Write a description of class calculator here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Calculator
{
// instance variables - replace the example below with your own
private int x;
private int startingNumber = 1;
private int stepCount;
private int numberStorage;
private int currentRecordStart;
private int currentRecordSteps = 0;
/**
* a string and int value to track multiple starting numbers with the same number of steps
*/
private String tieNote = "no ties";
private int multiTie = 0;
/**
* Constructor for objects of class calculator
*/
public Calculator()
{
x = 0;
}
/**
* begins function
*/
public void initiater()
{
numberStorage = 0;
stepCount = 0;
startingNumber = 1;
currentRecordStart = 1;
currentRecordSteps = 0;
stepCount = 0;
recordHolder(1,1);
}
/**
* starts next rotation
*/
public void steprunner()
{
++startingNumber;
System.out.println("starting rotation " + startingNumber + " current record " + currentRecordSteps);
stepCount = 0;
numberStorage = 0;
recordHolder(startingNumber, collatzSequence(startingNumber));
}
/**
* Runs collatz sequence and updates a variable with the number of steps.
*/
public int collatzSequence(int N)
{
numberStorage = 0;
numberStorage = N;
if (N == 1)
{
return stepCount;
}
else if ( (N & 1) == 0)
{
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
else if ( (N & 1) != 0)
{
numberStorage = 3 * numberStorage + 1;
++stepCount;
numberStorage = numberStorage / 2;
++stepCount;
return collatzSequence(numberStorage);
}
return stepCount;
}
/**
* stores record and starts next cycle
*/
public void recordHolder(int startingnumber, int stepcount)
{
if (startingNumber <= 999999)
{
if (stepcount > currentRecordSteps)
{
currentRecordSteps = stepcount;
currentRecordStart = startingnumber;
tieNote = "no ties";
multiTie = 0;
System.out.println("a tie occured!");
}
else if (stepcount == currentRecordSteps)
{
tieNote = ("starting number " + startingnumber + " also had " + stepcount + "steps");
++multiTie;
System.out.println("a secondary tie occured!");
}
steprunner();
}
if (startingNumber == 999999)
{
simulationEnder();
}
}
/**
* ends simulation
*/
public void simulationEnder()
{
System.out.println("the number with the highest number of steps was " + currentRecordStart +
" with " + currentRecordSteps + " steps!");
}
}
I'm not going to read your code. But I can show you a solution, written in pseudocode, that is simple and quick:
function euler14(n):
cs := makeArray(1..n)
maxX, maxLen, cs[1] := 1, 1, 1
for k from 2 to n
c, s := 0, k
while k <= s
if s % 2 == 0
s := s / 2
else
s := 3 * s + 1
c := c + 1
cs[k] := cs[s] + c
if maxLen < xs[k]
maxX, maxLen := k, cs[k]
return maxX
The trick is to calculate and save the values of the lengths of the collatz chain, in order starting from 1; then, if a future sequence drops below its starting point, calculation stops in favor of a simple lookup. Here the cs array is the cache, k is the index of the chain that is currently being computed, s is the current item in the chain, and c is the current length of the chain. Computing euler14(1000000) should take no more than a second or two.
Related
Question:
A class SeriesSum is designed to calculate the sum of the following series:
Class name : SeriesSum
Data members/instance variables:
x : to store an integer number
n : to store number of terms
sum : double variable to store the sum of the series
Member functions:
SeriesSum(int xx, int nn) : constructor to assign x=xx and n=nn
double findfact(int m) to return the factorial of m using recursive
technique.
double findpower(int x, int y) : to return x raised to the power of y using
recursive technique.
void calculate( ) : to calculate the sum of the series by invoking
the recursive functions respectively
void display( ) : to display the sum of the series
(a) Specify the class SeriesSum, giving details of the constructor(int, int),
double findfact(int), double findpower(int, int), void calculate( ) and
void display( ).
Define the main( ) function to create an object and call the
functions accordingly to enable the task.
Code:
class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{ for(int i=2;i<=n;i+=2)
sum += findpower(x,i)/findfact(i-1);
}
void display()
{ System.out.println("sum="+ sum);
}
static void main()
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
MyProblem:
I am having problems in understanding that when i= any odd number (Taking an example such as 3 here)then it value that passes through findfact is (i-1)=2 then how am I getting the odd factorials such as 3!
Any help or guidance would be highly appreciated.
Optional:
If you can somehow explain the recursion taking place in the findpower and findfactorial,it would be of great help.
Take a closer look a the loop. i starts at 2 and is incremented by 2 every iteration, so it is never odd. It corresponds to the successive powers of x, each of which is divided by the factorial of i -1 (which IS odd).
As for the recursion in findfact, you just need to unwrap the first few calls by hand to see why it works :
findfact(a) = a * findfact(a -1)
= a * (a - 1) * findfact(a -2)
= a * (a - 1) * (a - 2) * findfact(a - 3)
...
= a * (a - 1) * (a - 2) * ... * 2 * findfact(1)
= a * (a - 1) * (a - 2) * ... * 2 * 1
= a!*
The same reasoning works with findpower.
As a side note, while it may be helpful for teaching purposes, recursion is a terrible idea for computing factorials or powers.
I'm not sure I understand your question correctly, but I try to help you the best I can.
I am having problems in understanding that when i= any odd number
In this code i never will be any odd number
for(int i=2;i<=n;i+=2)
i will be: 2 , 4 , 6 , 8 and so on because i+=2
The Recursion
The findfact() function in a more readable version:
double findfact(int a){
if(a < 2 ){
return 1;
} else {
return a * findfact(a - 1);
}
}
you can imagine it as a staircase, every call of findfact is a step:
We test: if a < 2 then return 1 else we call findfact() again with a-1 and multiply a with the result of findfact()
The same function without recursion:
double findfact(int a){
int sum = 1;
for(int i = a; i > 0; i--){
sum *= i;
}
return sum;
}
Same by the findpower function:
if b == 0 then return 1 else call findpower() with a, b-1 and multiply the return value of findpower() with a
So the last called findpower() will return 1 (b = 0)
The second last findpower() will return a * 1 (b = 1)
The third last findpower() will return a * a * 1 (b = 2)
so you can see findpower(a, 2) = a * a * 1 = a^2
Hope I could help you
Try to run below code, it will clear all your doubts (i have modified some access specifier and created main method)
public class SeriesSum
{
int x,n;
double sum;
SeriesSum(int xx,int nn)
{ x=xx;
n=nn;
sum=0.0;
}
double findfact(int a)
{ return (a<2)? 1:a*findfact(a-1);
}
double findpower(int a, int b)
{ return (b==0)? 1:a*findpower(a,b-1);
}
void calculate()
{
System.out.println("x ="+x);
System.out.println("n ="+n);
for(int i=2;i<=n;i+=2){
System.out.println(x+"^"+i+"/"+(i-1)+"!" +" = " +(findpower(x,i)+"/"+findfact(i-1)) );
//System.out.println(findpower(x,i)+"/"+findfact(i-1));
sum += findpower(x,i)/findfact(i-1);
}
}
void display()
{ System.out.println("sum="+ sum);
}
public static void main(String arg[])
{ SeriesSum obj = new SeriesSum(3,8);
obj.calculate();
obj.display();
}
}
// ----- output ----
x =3
n =8
3^2/1! = 9.0/1.0
3^4/3! = 81.0/6.0
3^6/5! = 729.0/120.0
3^8/7! = 6561.0/5040.0
sum=29.876785714285713
You can simplify the summation and get rid of power and factorial. Please notice:
The very first term is just x * x
If you know term item == x ** (2 * n) / (2 * n - 1)! the next one will be item * x * x / (2 * n) / (2 * n + 1).
Implementation:
private static double sum(double x, int count) {
double item = x * x; // First item
double result = item;
for (int i = 1; i <= count; ++i) {
// Next item from previous
item = item * x * x / (2 * i) / (2 * i +1);
result += item;
}
return result;
}
In the real world, you can notice that
sinh(x) = x/1! + x**3/3! + x**5/5! + ... + x**(2*n - 1) / (2*n - 1)! + ...
and your serie is nothing but
x * sinh(x) = x**2/1! + x**4 / 3! + ... + x**(2*n) / (2*n - 1)! + ...
So you can implement
private static double sum(double x) {
return x * (Math.exp(x) - Math.exp(-x)) / 2.0;
}
I have a method for finding, wheter a number is a prime or not. It is working in my test class, but when I am using System.outprintf, it fails.
Same for the repDigit method.
Any help would be appreciated
Method for finding prime number:
/**
* Checks whether the number is a prime number.
*
* #param number Any number
* #return true if the number is prime, otherwise false
*/
public static boolean isPrime(int number) {
boolean isPrime = true;
if (number < 2) {
isPrime = false;
} else {
// Start counting from two to begin with even numbers
for (int i = 2; i < number/2; ++i) {
if (number % i == 0) {
isPrime = false;
}
}
}
return isPrime;
}
Method for finding repDigit:
/**
* This method checks if numbers, after each other, are the same. We take
* modulus of the number, in order to get the last digit, as long as the
* number is above 0. The number is divided by 10, to end up with all
* remaining numbers. Then it checks, if the last digit + the remaining are
* the same
*
* #param number
* #return
*/
public static boolean isRepDigit(int number) {
int repDigit = number % 10;
boolean toReturn = true;
if (number < 10) {
toReturn = false;
} else {
while (number > 0) {
int digit = number % 10;
number = number / 10;
if (repDigit != digit) {
toReturn = false;
}
}
}
return toReturn;
}
Main method:
public static void main(String[] args) {
final int START = 5;
final int END = 100;
final int SPACE = digitCount(END);
for (int i = START; i < END; i++) {
System.out.printf("%" + SPACE + "d is a repdigit &n", isRepDigit(i));
System.out.printf("%" + SPACE + "d is a prime &n", isPrime(i));
}
}
Error message:
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Boolean
at java.util.Formatter$FormatSpecifier.failConversion(Formatter.java:4302)
at java.util.Formatter$FormatSpecifier.printInteger(Formatter.java:2793)
at java.util.Formatter$FormatSpecifier.print(Formatter.java:2747)
at java.util.Formatter.format(Formatter.java:2520)
at java.io.PrintStream.format(PrintStream.java:970)
at java.io.PrintStream.printf(PrintStream.java:871)
at Grp17_ueb01.main(Grp17_ueb01.java:164)
C:\Users\rasmu\Documents\NetBeansProjects\ueb01\nbproject\build-impl.xml:1040: The following error occurred while executing this line:
C:\Users\rasmu\Documents\NetBeansProjects\ueb01\nbproject\build-impl.xml:805: Java returned: 1
BUILD FAILED (total time: 1 second)
I think you misunderstood the meaning of the second argument of printf.
Here d in your string is supposed to be replaced by as a decimal, given as second argument. And the boolean isRepDigit(i) cannot be converted as a decimal.
The printf method documentation may be found here.
The Format string syntax is explained here.
What I think you wanted is:
if (isRepDigit(i)) {
System.out.printf("%" + SPACE + "d is a repdigit \n", i);
}
if (isPrime(i)) {
System.out.printf("%" + SPACE + "d is a prime \n", i);
}
Question
Given N and M, write an equation using left shift operators whose
result will be equal to the product N * M.
Input : First line has 0 < T ≤ 50000 denoting number of test cases.
Next T lines have two integers 0 < N, M ≤ 10¹⁶.
Output : For each test case print an equation for N * M resembling
(N << p1) + (N << p2)+ ...+(N << pk) where p1 ≥ p2 ≥ ... ≥ pk
and k is minimum.
SAMPLE INPUT SAMPLE OUTPUT
2
2 1 (2<<0)
2 3 (2<<1) + (2<<0)
Time Limit: 1.0 sec
My Solution 1st approach
int dig = (int)(Math.floor(Math.log10(m)/Math.log10(2))+1);
boolean flag = false;
for(long i = dig; i>=0; --i) {
if(((m>>(i-1l)) & 1l) == 1l) {
if(flag)
System.out.print(" + ("+n+ "<<"+(i-1)+")");
else {
System.out.print("("+n+"<<"+(i-1)+")");
flag = true;
}
}
}
Second Approach
boolean[] arr = new boolean[dig];
int i = dig-1;
while(m > 0) {
if((m&1) == 1 ) {
arr[i] = true;
}
i--;
m = m>>1l;
}
int j = dig-1;
for( i = 0; i < dig; ++i) {
if(arr[i]) {
if(flag)
System.out.print(" + ("+n+"<<"+j+")");
else {
System.out.print("("+n+"<<"+j+")");
flag = true;
}
}
j--;
}
In both cases I am getting 5 correct out of 8 and rest 3 are TLE why?
I don't actually see anything in both of your approaches preventing some ten-thousands of products of numbers up to 57 bit to be represented as Strings in one second:
TLE may be due to System.out.print() taking an inordinate amount of time.
That said, use a utility like
/** builds <code>n * m</code> in the form
* <code>(n<<p1) + (n<<p2) + ... + (n<<pk)</code>
* using left shift.
* #param n (0 < multiplicand <= 10**16)
* #param m 0 < multiplier <= 10**16
* #return a verbose <code>String</code> for <code>n * m</code>
*/
static String verboseBinaryProduct(Object n, long m) {
int shift = Long.SIZE - Long.numberOfLeadingZeros(m) - 1;
final long highest = 1 << shift;
final StringBuilder binary = new StringBuilder(42);
final String chatter = ") + (" + n + "<<";
final long rest = highest - 1;
while (true) {
if (0 != (highest & m))
binary.append(chatter).append(shift);
if (0 == (rest & m)) {
binary.append(')');
return binary.substring(4);
}
m <<= 1;
shift -= 1;
}
}
and System.out.println(verboseBinaryProduct(n, m));.
I need to create an array list to save the value of resistors entered by user. Then I need to ask user which type of method to calculate his answer with, then return back answer. The do while loop needs to keep asking for resistors values until user enter the number zero. The calculations have to be pulled from a class Resistance to Main.
**CLASS***
import java.util.ArrayList;
public class Resistance {
/**
* Holds an object type.
*/
public int userChoice;
ArrayList<Double> resistor = new ArrayList<Double>();
/**
*Chooses which process follows next.
*#return circuitType
*/
public final double calculateResistance() {
if (userChoice == 1) {
return calculateSeriesResistance();
} else {
return calculaParallelResistance();
}
}
/**Returns object of parallel circuit.
*
* #return 1 / runningResistance.
*/
public double calculaParallelResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.lenght; ++index) {
runningResistance = runningResistance
+ +1 / resistor.lenght;
}
return 1 / runningResistance;
}
/**Returns object of series circuit.
*
* #return runningResistance.
*/
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.length; ++index) {
runningResistance = runningResistance + resistor[index];
}
return runningResistance;
}
}
***MAIN********
import java.text.DecimalFormat;
import java.util.Scanner;
public class Main {
/**
* Makes a Constant.
*/
public final static int DONE = 0;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_SERIES = 1;
/**
* Makes a Constant.
*/
public static final int USER_CHOICE_PARALLEL = 2;
public static void main(final String[] args) {
// TODO Auto-generated method stub
DecimalFormat f = new DecimalFormat("##.00");
Resistance myRes = new Resistance();
Scanner keyboard = new Scanner(System.in);
//Display Purpose
System.out.println("\nThis program will calculate "
+ "the resistance of a Parallel or Series "
+ "Circuit\n");
//Display instructions
System.out.println("Please enter the value of your "
+ "resistors separately, when done press 0 (zero)");
int n = 0;
do {
System.out.println("Enter Resistor #" + ++n);
myRes.resistor.add(keyboard.nextDouble());
} while (myRes.resistor > 0);
// Ask Which Method To Use,
do {
System.out.println("\nEnter 1 to calculate "
+ "a Series Circuit "
+ "or 2 for a Parallel Circuit");
myRes.userChoice = keyboard.nextInt();
// Ask user again in case he enters something else
} while (myRes.userChoice != USER_CHOICE_PARALLEL
&& myRes.userChoice != USER_CHOICE_SERIES);
//Output the total resistance
System.out.printf("\nThe Total Resistance is "
+ f.format(myRes.calculateResistance()));
}
}
As said, there are few isues with your code, let's break it down step by step.
First, ArrayList doesn't have a field called length, you want to use size() instead.
Next, your method of calculating parallel resistance is wrong. You are not iterating over your resistors, instead you're using number of resistors to calculate. The correct formula is:
1 / Rtotal = 1 / R1 + 1 / R1 + 1 / R3 + ...
Change your code to:
public double calculaParallelResistance() {
double runningResistance = 0;
//use size() instead of length, which doesn't exist in ArrayList
for (int index = 0; index < resistor.size(); index++) {
//also, iterate over each resistor's value, and to get it,
//use...err, get() method :)
runningResistance += (1 / resistor.get(index));
}
return 1 / runningResistance;
}
Your method calculateSeriesResistance() also has an issue: you can't access object by using array notation, as in resistance[index]. Use get() method, so the correct code is:
private double calculateSeriesResistance() {
double runningResistance = 0;
for (int index = 0; index < resistor.size(); index++) {
runningResistance += resistor.get(index);
}
return runningResistance;
}
Now, to the main method. Your first 'do' loop is checking against number of resistors in your ArrayList, not against 0 value entered by user. You could use while loop instead and break when 0 entered:
//holds current resistor's value
Double val;
while(true) {
System.out.println("Enter Resistor #" + ++n);
val = keyboard.nextDouble();
//only add if higher than 0
if (val > 0.0) {
myRes.resistor.add(val);
}
//0 entered, so finish the loop
else break;
}
With the help of some very nice people from this forum I've been able to translate some c++ into java language, but I'm not sure how to call this classes. Bassically what they are supposed to do is to return a "gen4 style" curve. If someone have an idea how to get this running please let me know!
/*
Derived from gen4 from the UCSD Carl package, described in F.R. Moore,
"Elements of Computer Music." It works like setline, but there's an
additional argument for each time,value pair (except the last). This
arg determines the curvature of the segment, and is called "alpha" in
the comments to trans() below. -JGG, 12/2/01
http://www.music.columbia.edu/cmc/rtcmix/docs/docs.html (maketable/gen4)
trans(a, alpha, b, n, output) makes a transition from <a> to <b> in
<n> steps, according to transition parameter <alpha>. It stores the
resulting <n> values starting at location <output>.
alpha = 0 yields a straight line,
alpha < 0 yields an exponential transition, and
alpha > 0 yields a logarithmic transition.
All of this in accord with the formula:
output[i] = a + (b - a) * (1 - exp(i * alpha / (n-1))) / (1 - exp(alpha))
for 0 <= i < n
*/
import java.lang.Math;
private static final int MAX_POINTS =1024;
public class gen{
int size; /* size of array to load up */
int nargs; /* number of arguments passed in p array */
float []pvals; /* address of array of p values */
double []array; /* address of array to be loaded up */
int slot; /* slot number, for fnscl test */
}
public static void fnscl(gen g) {
}
static void trans(double a, double alpha, double b, int n, double[] output) {
double delta = b - a;
if (output.length <= 1) {
output[0] = a;
return;
}
double interval = 1.0 / (output.length - 1);
if (alpha != 0) {
double denom = 1 / (1 - Math.exp(alpha));
for (int i = 0; i < output.length; i++)
output[i] = a + (1 - Math.exp(i * alpha * interval)) * delta * denom;
} else {
for (int i = 0; i < output.length; i++)
output[i] = a + i * delta * interval;
}
}
public static double gen4(gen g) {
int i;
int points = 0;
int seglen = 0;
double factor;
double time [] = new double[MAX_POINTS];
double value [] = new double[MAX_POINTS];
double alpha [] = new double[MAX_POINTS];
double ptr [];
if (g.nargs < 5 || (g.nargs % 3) != 2) /* check number of args */
System.out.println("gen4 usage: t1 v1 a1 ... tn vn");
if ((g.nargs / 3) + 1 > MAX_POINTS)
System.out.println("gen4 too many arguments");
for (i = points = 0; i < g.nargs; points++) {
time[points] = g.pvals[i++];
if (points > 0 && time[points] < time[points - 1])
System.out.println("gen4 non-increasing time values");
value[points] = g.pvals[i++];
if (i < g.nargs)
alpha[points] = g.pvals[i++];
}
factor = (g.size - 1) / time[points - 1];
for (i = 0; i < points; i++)
time[i] *= factor;
ptr = g.array;
for (i = 0; i < points - 1; i++) {
seglen = (int) (Math.floor(time[i + 1] + 0.5)
- Math.floor(time[i] + 0.5) + 1);
trans(value[i], alpha[i], value[i + 1], seglen, ptr);
ptr[i] += seglen - 1;
}
fnscl(g);
return 0.0;
}
If I understand your question correctly and you want to execute your program, you need some adjustments to your code.
You need to have a class. To execute it, you need a special main method.
/**
*Derived from...
*/
import java.lang.Math;
class Gen4Func {
class Gen {
// insert from question
}
public static void main(String[] args) {
// prepare parameters
// ...
// call your function
trans( ... );
// do more stuff
// ...
}
public static void fnscl(gen g) {
}
static void trans(double a, double alpha, double b, int n, double[] output) {
// insert from above
}
}
Save this to Gen4Func.java (must match class name). Then execute from via
> java Gen4Func
As I said: If I understand your question correctly.
HTH,
Mike
Bulky, copypaste to Gen.java and try setting Gen class fields with test values in main() method.
/*
* Derived from gen4 from the UCSD Carl package, described in F.R. Moore,
* "Elements of Computer Music." It works like setline, but there's an additional
* argument for each time,value pair (except the last). This arg determines the
* curvature of the segment, and is called "alpha" in the comments to trans()
* below. -JGG, 12/2/01
*
* http://www.music.columbia.edu/cmc/rtcmix/docs/docs.html (maketable/gen4)
*
*
*
* trans(a, alpha, b, n, output) makes a transition from <a> to <b> in <n>
* steps, according to transition parameter <alpha>. It stores the resulting <n>
* values starting at location <output>. alpha = 0 yields a straight line, alpha
* < 0 yields an exponential transition, and alpha > 0 yields a logarithmic
* transition. All of this in accord with the formula: output[i] = a + (b - a) *
* (1 - exp(i * alpha / (n-1))) / (1 - exp(alpha)) for 0 <= i < n
*/
public class Gen {
private static final int MAX_POINTS = 1024;
int size; //size of array to load up
int nargs; //number of arguments passed in p array
float[] pvals; //address of array of p values
double[] array; //address of array to be loaded up
int slot; //slot number, for fnscl test
public static void main(String[] args) {
Gen g = new Gen();
//initialize Gen fields here..
Gen.gen4(g);
}
public static void fnscl(Gen g) {
}
public static void trans(double a, double alpha, double b, int n, double[] output) {
double delta = b - a;
if (output.length <= 1) {
output[0] = a;
return;
}
double interval = 1.0 / (output.length - 1);
if (alpha != 0) {
double denom = 1 / (1 - Math.exp(alpha));
for (int i = 0; i < output.length; i++) {
output[i] = a + (1 - Math.exp(i * alpha * interval)) * delta * denom;
}
} else {
for (int i = 0; i < output.length; i++) {
output[i] = a + i * delta * interval;
}
}
}
public static double gen4(Gen g) {
int i;
int points = 0;
int seglen = 0;
double factor;
double time[] = new double[MAX_POINTS];
double value[] = new double[MAX_POINTS];
double alpha[] = new double[MAX_POINTS];
double ptr[];
if (g.nargs < 5 || (g.nargs % 3) != 2) /*
* check number of args
*/ {
System.out.println("gen4 usage: t1 v1 a1 ... tn vn");
}
if ((g.nargs / 3) + 1 > MAX_POINTS) {
System.out.println("gen4 too many arguments");
}
for (i = points = 0; i < g.nargs; points++) {
time[points] = g.pvals[i++];
if (points > 0 && time[points] < time[points - 1]) {
System.out.println("gen4 non-increasing time values");
}
value[points] = g.pvals[i++];
if (i < g.nargs) {
alpha[points] = g.pvals[i++];
}
}
factor = (g.size - 1) / time[points - 1];
for (i = 0; i < points; i++) {
time[i] *= factor;
}
ptr = g.array;
for (i = 0; i < points - 1; i++) {
seglen = (int) (Math.floor(time[i + 1] + 0.5)
- Math.floor(time[i] + 0.5) + 1);
trans(value[i], alpha[i], value[i + 1], seglen, ptr);
ptr[i] += seglen - 1;
}
fnscl(g);
return 0.0;
}
}
In Java, stand alone methods are not allowed. You should make them member of some class. In your case, it seems that 2 of your methods are using class gen as argument fnscl() amd gen4(). You can make them as member methods. The other one can remain static within class.
public class gen{
// data ...
public void fnscl () { ... } // member method
public double gen4 () { ... } // member method
// static method
public static void trans(double a, double alpha, double b, int n, double[] output) { ... }
}
main() also should be part of some class. I leave that choice up to you.
Java is a fully object oriented language in terms of paradigms. (Not as c++ which is also procedural), that's why as Kerrek SB said all methods has to be declared and defined inside a class.
What he was mistaken is that a file can contain only one public class and it has to be named exactly as the file. But it can also contain any number non-public classes with arbitrary names.
To run the program, you have to first compile the file with javac [filename].java then run it with java [classname] without! .class
One more thing. You can't declare a method like this:
public void foo();
The compiler will consider it to be an abstract method and raise an error message.