Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Пара задач на смекалку


Автор: Самозванка 25.5.2010, 15:03
Как не используя циклы распечатать все числа от 1 до 1 000 000 ?  smile 

Есть связаный однонаправленный список... Каким образом распечатать его задом наперед.... Привести несколько вариантов...

Автор: susanin 25.5.2010, 15:05
Цитата(Самозванка @  25.5.2010,  15:03 Найти цитируемый пост)
Как не используя циклы распечатать все числа от 1 до 1 000 000 ?

рекурсией?

Автор: LSD 25.5.2010, 15:11
Цитата(Самозванка @  25.5.2010,  16:03 Найти цитируемый пост)
Как не используя циклы распечатать все числа от 1 до 1 000 000?

В http://forum.vingrad.ru/forum/java-general.html есть этот вопрос и ответы на него.
А вот вторая задачка интересная, перепости ее туда пожалуйста. А эту тему я закрою во избежание....


Цитата(susanin @  25.5.2010,  16:05 Найти цитируемый пост)
рекурсией?

Тепло, но совсем не точно, StackOverflowError пока никто не отменял.

Автор: Самозванка 25.5.2010, 15:23
LSD, оки

Добавлено через 14 минут и 30 секунд
LSD, а пришли мне плиз в личку где решения первой задачи в той теме)))

Автор: powerOn 25.5.2010, 15:38
Цитата(Самозванка @  25.5.2010,  16:03 Найти цитируемый пост)
Как не используя циклы распечатать все числа от 1 до 1 000 000 ? 


Код

public class NewClass
{
    public static void main(String[] args)
    {
        new Thread(new SimpleRunnable(1)).start();
    }

    public static class SimpleRunnable implements Runnable
    {
        private int i;

        public SimpleRunnable(int i)
        {
            this.i = i;
        }

        @Override
        public void run()
        {
            if (i < 100000) {
                System.out.println("i = " + i);
                new Thread(new SimpleRunnable(i + 1)).start();
            }
        }
    }
}


Автор: Самозванка 25.5.2010, 15:51
powerOn, кстати хорошее решение, спасибо

Автор: powerOn 25.5.2010, 15:59
Самозванка, не за что, медленное оно.

Автор: susanin 25.5.2010, 17:47
powerOn, а если на плюсах и без потока?возможно?

Автор: powerOn 25.5.2010, 19:09
Цитата(susanin @  25.5.2010,  18:47 Найти цитируемый пост)
powerOn, а если на плюсах и без потока?возможно? 

мне в голову пока не приходит другое решение =) на прологе возможно - там хвостовая рекурсия есть.

Автор: susanin 25.5.2010, 19:54
а если вот так?
Код

static int n=0;
class myClass
{
public:
    myClass()
    {
        cout<<n++;
    }
};
int main()
{
    myClass m[1000000];
}

Автор: kemiisto 25.5.2010, 20:03
Цитата(susanin @  25.5.2010,  20:54 Найти цитируемый пост)
а если вот так?

Хе-хе. Его величество goto! smile 

Код

#include<stdio.h>

int main()
{
  int i = 0;
start:
  i = i + 1;
  printf("%d\n", i);

  if (i < 1000000)
    goto start;
    
  return 0;     
}


На С.

Автор: pathfinder 25.5.2010, 20:25
Код

public class RecursiveClass {

    public static void main(String[] args) {
        new RecursiveClass(0);
    }

    public RecursiveClass(int value) {
        System.out.println("Value : "+value);
        if (value < 1000000) {
            new RecursiveClass(value + 1);
        }
    }

}

Автор: Самозванка 25.5.2010, 20:36
а вторую задачку?)  smile 

Автор: pathfinder 25.5.2010, 20:50
Еще более красивое решение первой задачи, поскольку приведенное выше 100 вылезет за пределы стека.

Код

public class BinaryRecursiveClass {
    
    public static int value = 0;
    
    public static void main(String[] args) {
        new BinaryRecursiveClass(0);
    }
    
    public class BinaryRecursiveClass(int depth) {
        System.out.println("Value = " + (value++));
        if (depth < 32) {
            new BinaryRecursiveClass(depth + 1);
            new BinaryRecursiveClass(depth + 1);
        }
    }
    
}

Автор: powerOn 25.5.2010, 20:58
Решение второй задачи (рекурсивный подъем):

Код

public class Main
{
    public static class Node
    {
        private Node next;
        private int digit;

        public Node(Node next, int digit)
        {
            this.next = next;
            this.digit = digit;
        }

        public void printReverse()
        {
            if (next != null) {
                next.printReverse();
            }
            System.out.println(digit);
        }
    }

    public static void main(String[] args)
    {
        Node root = new Node(new Node(new Node(new Node(new Node(new Node(null, 6), 5), 4), 3), 2), 1);
        root.printReverse();
    }
}


Автор: ivanovpv 26.5.2010, 13:29
Хммм... Есть такой хак:
Код

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.*;

public class Tester
{
    public static void main(String args[])
    {
        Tester obj = new Tester();
        StringBuffer sb=new StringBuffer();
        sb.append("public class MyPrinter\n");
        sb.append("{\n");
        sb.append("public static void main(String[] args)\n");
        sb.append("{\n");
        sb.append("\tfor(int i=0; i < 1000000; i++)\n");
        sb.append("\t\tSystem.out.println(i);\n");
        sb.append("\t}\n");
        sb.append("}\n");
        File file=new File("MyPrinter.java");
        try
        {
            file.delete();
            file.createNewFile();
            OutputStream os=new FileOutputStream(file, false);
            Writer writer=new OutputStreamWriter(os);
            writer.write(sb.toString());
            writer.close();
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
            StandardJavaFileManager filemanager = compiler.getStandardFileManager(null, null, null);
            Iterable compilationUnits = filemanager.getJavaFileObjects(file);
            compiler.getTask(null, filemanager, null, null, null, compilationUnits).call();
            filemanager.close();
            Runtime.getRuntime().exec("java MyPrinter > output.txt");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}


Суть состоит в том, что на лету создаем классик который печатает означенные от 1 до мульона, компилим его и тут же запускаем. Формально цикла в исходниках нет  smile

Добавлено через 2 минуты и 4 секунды
Можно конечно и покруче навертеть. Создать класс через рефлексию схватить его метод и запустить и не маяться вызовом Runtime.exec()

Автор: ivanovpv 27.5.2010, 10:08
Цитата(Самозванка @  25.5.2010,  15:03 Найти цитируемый пост)
Как не используя циклы распечатать все числа от 1 до 1 000 000 ?  


Придумал еще 1 вариант - на это раз честный без хака.

Код

import java.io.*;

public class Tester2
{
    public static void main(String args[])
    {
        byte[] buffer=new byte[1000000];
        MyOutputStream mos=new MyOutputStream();
        try
        {
            mos.write(buffer);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

class MyOutputStream extends OutputStream
{
    static int counter=0;

    @Override
    public void write(int b) throws IOException
    {
        System.out.println(counter++);
    }
}



Автор: pathfinder 27.5.2010, 12:20
ivanovpv, все ж таки цикл присутствует в OutputStream write(byte[] b).

Автор: mrbrooks 27.5.2010, 16:15
Цитата(susanin @  25.5.2010,  18:47 Найти цитируемый пост)
powerOn, а если на плюсах и без потока?возможно? 

дык той же рекурсией аля:
Код

#include <iostream>

void rec(int param)
{
    if (param <= 1000000)
    {
        std::cout << param++ << std::endl;
        rec(param);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    rec(0);
    return 0;
}


Добавлено через 2 минуты и 8 секунд
Цитата(kemiisto @  25.5.2010,  21:03 Найти цитируемый пост)
Хе-хе. Его величество goto! smile 

гы

Автор: susanin 27.5.2010, 16:32
Цитата(mrbrooks @  27.5.2010,  16:15 Найти цитируемый пост)
дык той же рекурсией аля:

я этот вариант еще во 2 посте предложил...

Цитата(LSD @  25.5.2010,  15:11 Найти цитируемый пост)
Цитата(susanin @  25.5.2010,  16:05 )рекурсией?Тепло, но совсем не точно, StackOverflowError пока никто не отменял.


Автор: Kircul 27.5.2010, 16:57
Цитата(Самозванка @  25.5.2010,  14:03 Найти цитируемый пост)
Есть связаный однонаправленный список... Каким образом распечатать его задом наперед.... Привести несколько вариантов... 


Записать в стек и выводить из стека. Такой вариант не предлагали?

Автор: Kircul 27.5.2010, 17:14
ivanovpv, твоя идея с интерпретацией кода может быть реализована проще.
Код

public class T {

    public static void main(String[] args) throws ScriptException {
        new ScriptEngineManager().getEngineByName("JavaScript")
                              .eval("for(var i = 1; i <=10; i++) {println(i);}");
    }

}


Правда в таком случае код пишется на JS, а не на Java.

Автор: Kircul 27.5.2010, 17:48
Вот вариант решения первой задачи даже без циклов в JS:
Код

public class T {

    public static void main(String[] args) throws ScriptException {
        ScriptEngineManager engineManager = new ScriptEngineManager();
        engineManager.getEngineByName("js")
                .eval("var i = 1;\n" +
                        "function f() {" +
                        "if (i <= 1000000) {" +
                        "println(i);" +
                        "f(i++);" +
                        "}" +
                        "}\n" +
                        "f();");
    }

}

Только запускать надо с параметрами "-Xms512m -Xmx512m" Этого достаточно.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)