【问题标题】:Resizing Arrays for Speed调整数组大小以提高速度
【发布时间】:2014-04-09 23:59:09
【问题描述】:

所以,我正在用 Java 编写 Befunge 解释器。我几乎把它都记下来了,除了我想不出一个很好的解决Funge Space问题的方法。目前我正在使用 Befunge 93 规范中规定的样式,它是一个 80x25 数组来保存代码。

不过,在 Funge 中,我应该有一个“无限”的代码数组(或 4,294,967,296 x 4,294,967,296,在两个维度上为 -2,147,483,648 到 2,147,483,648),但显然拥有这么多空间绝不是一个好主意分配。但除此之外,每次程序越界时创建一个新数组并将每个字符都复制到其中似乎不是一个好主意。有没有我想念的这个问题的解决方案?

所以基本上,我的问题是每次超出范围时我都需要以某种方式扩展数组,或者使用某种其他数据结构。有什么建议吗?

Funge 98 specs

另外,顺便说一句,我仍然不知道如何发音 Befunge 或 Funge,我总是像“Bee-funj”和“funj”这样说

【问题讨论】:

  • 对不起,我忘了说也需要负坐标。有没有办法让它发挥作用?

标签: java arrays interpreter language-features


【解决方案1】:

没有阅读规范(不 - 我的意思是,只是 !):4,294,967,296 x 4,294,967,296 数组显然是一个高度理论化的构造,并且这些“数组条目”中只有一小部分可以并将永远被使用。

除此之外:无论您使用数组还是任何其他集合,您都会遇到索引问题:数组索引只能是 int 值,但 4,294,967,296 是 Integer.MAX_VALUE 的两倍大(有在 Java 中没有无符号整数)。

但是,表示这种“无限大”稀疏二维数组的一种方法是将长值对(x 和 y 坐标)映射到数组条目的映射。大致是这样的:

import java.util.HashMap;
import java.util.Map;

interface Space<T> 
{
    void set(long x, long y, T value);
    T get(long x, long y);
}

class DefaultSpace<T> implements Space<T>
{
    private final Map<LongPair, T> map = new HashMap<LongPair, T>();

    @Override
    public void set(long x, long y, T value)
    {
        LongPair key = new LongPair(x,y);
        if (value == null)
        {
            map.remove(key);
        }
        else
        {
            map.put(key, value);
        }
    }

    @Override
    public T get(long x, long y)
    {
        return map.get(new LongPair(x,y));
    }
}


class LongPair
{
    private final long x;
    private final long y;

    LongPair(long x, long y)
    {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString()
    {
        return "("+x+","+y+")";
    }

    @Override
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + (int) (x ^ (x >>> 32));
        result = prime * result + (int) (y ^ (y >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        LongPair other = (LongPair) obj;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }

}

【讨论】:

  • 抱歉,我忘了说它也必须有负值,所以它应该是 -2,147,483,648 到 2,147,483,648,所以这都可以放入 int 中吗?
  • @Kyranstar 你对这些数字做了什么算术运算?
  • @Kyranstar 这些值几乎适合int,但使用我描述的方法(使用long),这个问题不再相关,我猜。
猜你喜欢
  • 1970-01-01
  • 2019-10-25
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 2013-09-14
  • 2013-10-09
  • 2021-05-19
  • 1970-01-01
相关资源
最近更新 更多