Ackermann iterativ in K&R C: falsche Werte

• ANSI C

Wann kapierst Du endlich daß es nicht nur eine ANSI Norm für C gibt???

• Jetzt erhalte ich folgende Ausgabe:

``````f(0, 0) = 1
f(0, 1) = 2
f(0, 2) = 3
f(0, 3) = 4
f(0, 4) = 5
f(1, 0) = 2
f(1, 1) = 3
f(1, 2) = 4
f(1, 3) = 5
f(1, 4) = 6
f(2, 0) = 3
f(2, 1) = 5
f(2, 2) = 7
f(2, 3) = 9
f(2, 4) = 11
f(3, 0) = 5
f(3, 1) = 8
f(3, 2) = 11
f(3, 3) = 14
f(3, 4) = 17
``````

Das ist bis `f(3, 0)` richtig und danach falsch...

``````unsigned long int ackermann(unsigned long int x, unsigned long int y)
{
struct ByteContent *a = 0, *b = 0;
unsigned long int *e = 0, *f = 0;
unsigned long int r = 0;
a = malloc(sizeof(struct ByteContent *));
e = malloc(sizeof(unsigned long int *) * 3);
a->content = (char *)e;
e[0] = x;
e[1] = y;
e[2] = 0;
insert(0, a);
while (len > 0)
{
a = delete (0);
e = (unsigned long int *)a->content;
r += e[2];
if (len > 0)
{
f = (unsigned long int *)get_byte_content(0);
f[2] = r;
}
if (e[0] == 0)
{

if (len == 0)
{
r += e[1] + 1;
}
else
{
f = (unsigned long int *)get_byte_content(0);
f[2] = e[1] + 1;
r += e[1] + 1;
}
}
else if (e[1] == 0)
{
b = malloc(sizeof(struct ByteContent *));
f = malloc(sizeof(unsigned long int *) * 3);
b->content = (char *)f;
f[0] = e[0] - 1;
f[1] = 1;
f[2] = 0;
insert(0, b);
}
else
{
/* Im else-Teil stimmt etwas nicht... */
b = malloc(sizeof(struct ByteContent *));
f = malloc(sizeof(unsigned long int *) * 3);
b->content = (char *)f;
f[0] = e[0] - 1;
f[1] = e[2];
f[2] = 0;
insert(0, b);

b = malloc(sizeof(struct ByteContent *));
f = malloc(sizeof(unsigned long int *) * 3);
b->content = (char *)f;
f[0] = e[0];
f[1] = e[1] - 1;
f[2] = 0;
insert(0, b);
}
free(e);
free(a);
}
return r;
}

int main(int argc, char **argv)
{
int x = 0, y = 0;
for (x = 0; x < 4; x++)
{
for (y = 0; y < 5; y++)
{
printf("f(%d, %d) = %lu\n", x, y, ackermann(x, y));
}
}
return 0;
}
``````

Wenn man sich die rekursive Definition anschaut: https://www.geeksforgeeks.org/ackermann-function/
was geschieht dann im ersten und im dritten Fall?

• Wann kapierst Du endlich daß es nicht nur eine ANSI Norm für C gibt???

Das stimmt nicht. Es gab nämlich nur eine ANSI Norm die von 1989, diese wurde 1990 zur ISO Norm. Danach gab es nur noch ISO Normen, die von ANSI als nationale Normen übernommen wurden.

• die von ANSI als nationale Normen übernommen wurden.

boah ey. wodurch sie zu ANSI Normen wurden. Dasselbe für die ÖNORM die regelmäßig DIN übernimmt.

• boah ey. wodurch sie zu ANSI Normen wurden.

Nein, nicht mehr – es sind INCITS/ISO/IEC Normen bzw. nur noch ISO/IEC Normen.

• Wollt ihr mir helfen oder lieber eine Runde schnacken?

• Wollt ihr mir helfen oder lieber eine Runde schnacken?

Hier eine Impl. in Java, nichrekursiv.
Ist leicht in C umzubauen.
Musst nur einen Stack programmieren (kleines Array und ein Pointer).

``````    public static int itFunc (int m, int n)
{
Stack<Integer> s = new Stack<Integer>();
while(!s.isEmpty())
{
m=s.pop();
if(m==0||n==0)
n+=m+1;
else{
n--;
}
}
return n;
}

``````

• @A-Grau Vielen Dank

in Java brauchte ich dafür zwei Stacks:

``````import java.util.ArrayDeque;

public class Test {
public static class Callee {
long x, y, r;

public Callee(long x, long y, long r) {
this.x = x;
this.y = y;
this.r = r;
}
}

public static long ackermann(int x, int y) {
long r = 0;
ArrayDeque<Callee> stack_a = new ArrayDeque<>();
ArrayDeque<Callee> stack_b = new ArrayDeque<>();
while (!(stack_a.isEmpty() && stack_b.isEmpty())) {
if (!stack_a.isEmpty()) {
Callee c = stack_a.removeFirst();
if (c.x == 0) {
r = c.y + 1;
} else if (c.y == 0) {
stack_a.addFirst(new Callee(c.x - 1, 1, 0));
} else {
stack_a.addFirst(new Callee(c.x, c.y - 1, 0));
stack_b.addFirst(new Callee(c.x - 1, 0, 0));
}
} else {
Callee c = stack_b.removeFirst();
c.y = r;
}
}
return r;
}

public static void main(String[] args) {
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 5; y++) {
System.out.printf("f(%d, %d) = %d%n", x, y, ackermann(x, y));
}
}
}
}
``````

Dass es auch einfacher geht, hast du ja schon gezeigt.

• in Java brauchte ich dafür zwei Stacks:

Das finde ich übertrieben. Hier eine Java-Version ganz ohne Stack (und mit Test):
gibt das aus, was du erwartest.

``````public class TestAck
{
public static void main(String[] args)
{
System.out.println(itFunc(0,4));
System.out.println(itFunc(1,0));
System.out.println(itFunc(1,1));
System.out.println(itFunc(1,2));
System.out.println(itFunc(1,3));
System.out.println(itFunc(1,4));
}

public static int itFunc (int m, int n)
{
int[] arr = new int[1000];
int p = 0;
arr[p++] = m;
while(p!=0)
{
m = arr[--p];
if(m==0||n==0)
n+=m+1;
else
{
arr[p++] = --m;
arr[p++] = ++m;
n--;
}
}
return n;
}
}

``````

Musst du nur noch C daraus machen. Ist aber jetzt besonders leicht.

• @EinNutzer0
Was genau soll der Verkettete-Liste-Unsinn hier?