RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 661416
Accepted
while1pass
while1pass
Asked:2020-05-03 18:35:48 +0000 UTC2020-05-03 18:35:48 +0000 UTC 2020-05-03 18:35:48 +0000 UTC

随机填充具有特定填充百分比的二维数组

  • 772

如何用指定填充百分比的数据填充二维数组?

例如,有一个数组 10 * 10,需要填充其中 30% 的单元格,因此,30 个单元格包含数据,70 个单元格为空。

该任务是解决另一个更大任务的结果,因此我在下面发布了所有代码。数组生成器方法 -generateData

我有三个解决方案。

第一种解决方案是递归调用遍历数组并逐渐用数据填充空单元格的函数。我们从数组的第零个元素开始,如果还没有达到填充数,就重新调用函数。缺点是递归方法本身不是很好,填充的单元格在一侧误入歧途。一个可能的解决方案是当到达数组的末尾时开始向相反的方向遍历

const getStyle = style => Object.assign({}, style);

const universeStyle = length => ({
  position: "relative",
  width: `${length * 10}px`,
  height: `${length * 10}px`,
  fontSize: "0",
  border: "1px solid #222"
});

const cellStyle = item => ({
  background: `${item.color}`,
  display: "inline-block",
  boxSizing: "border-box",
  width: "10px",
  height: "10px"
  //border: "1px solid grey"
});

const settingsStyle = () => ({
  margin: "10px 0 0 0"
});

const Cell = ({ item }) => (
  <div x={item.x} y={item.y} style={getStyle(cellStyle(item))} />
);

class Universe extends React.Component {
  render() {
    return (
      <div style={getStyle(universeStyle(this.props.width))}>
        {this.props.data.map(item => item.map(item => <Cell item={item} />))}
      </div>
    );
  }
}

class Settings extends React.Component {  
  render() {
    const {fill} = this.props;
    
    return (
      <div style={getStyle(settingsStyle())}>
        <button onClick={() => this.props.generateUniverse()}>Generate</button>
        <div>
          <input
            onChange={event => this.props.setFill(event)}
            type="range"
            value={fill} />
          <span>{fill}</span>
        </div>
      </div>
      )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      fill: 30
    };
  }
  
  componentDidMount() {
    this.generateUniverse()
  }
  
  getColor(colors = ['white', 'black']) {
    return colors[Math.floor(Math.random() * colors.length)];
  }

  generateData(width, fill) {
    const count = (width * width * fill) / 100;
    const getColor = this.getColor;
    let current = 0;
    const spaceData = Array.from({ length: width }).map((item, y) =>
        Array.from({ length: width }).map((item, x) => 
          ({y: y, x: x, color: 'white'})
      ))
    
    function fillData(data) {
      if (current < count) {
        data.forEach((line, y, data) => 
          line.forEach((obj, x, line) => {
            if (current < count) {
              obj.color = getColor();
              obj.color === 'black' ? current++ : null;
            } else { return data }
          })
        )        
        
        return fillData(data)
      }      
      
      return data
    }
    
    return fillData(spaceData)
  }
  
  generateUniverse() {
    this.setState({
        data: this.generateData(this.props.width, this.state.fill)
      });
  }
  
  redrawUniverse() {
    const idRedraw = setTimeout(() => {
      this.setState({
        data: this.generateData(this.props.width)
      }, this.redrawUniverse);
    }, 500);
    
    this.idRedraw = idRedraw;
  }
  
  stopRedraw() {
    clearTimeout(this.idRedraw)
  }
  
  setFill(event) {
    console.log(event.target.value)
    this.setState({fill: event.target.value})
  }
  
  render() {
    const [{width}, {data, fill}] = [this.props, this.state];
    
    return (
      <div>
        <Universe
          width={width}
          data={data}
        />
        <Settings
          fill={fill}
          setFill={(event) => this.setFill(event)}
          stopRedraw={() => this.stopRedraw()}
          startRedraw={() => this.redrawUniverse()}
          generateUniverse={() => this.generateUniverse()}
        />
      </div>
      )
  }
}

ReactDOM.render(<App width={10} />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

第二种解决方案是随机生成每个点的 X、Y 坐标,如果数组中所需的点已经填充 - 跳过,如果没有 - 填充。重复该过程,直到阵列已满。缺点是填充率高时,空点很少,程序将花费更多时间搜索空值。

const getStyle = style => Object.assign({}, style);

const universeStyle = length => ({
  position: "relative",
  width: `${length * 10}px`,
  height: `${length * 10}px`,
  fontSize: "0",
  border: "1px solid #222"
});

const cellStyle = item => ({
  background: `${item.color}`,
  display: "inline-block",
  boxSizing: "border-box",
  width: "10px",
  height: "10px"
});

const settingsStyle = () => ({
  margin: "10px 0 0 0"
});

const Cell = ({ item }) => (
  <div x={item.x} y={item.y} style={getStyle(cellStyle(item))} />
);

class Universe extends React.Component {
  render() {
    return (
      <div style={getStyle(universeStyle(this.props.width))}>
        {this.props.data.map(item => item.map(item => <Cell item={item} />))}
      </div>
    );
  }
}

class Settings extends React.Component {  
  render() {
    const {fill} = this.props;
    
    return (
      <div style={getStyle(settingsStyle())}>
        <button onClick={() => this.props.generateUniverse()}>Generate</button>
        <div>
          <input
            onChange={event => this.props.setFill(event)}
            type="range"
            value={fill} />
          <span>{fill}</span>
        </div>
      </div>
      )
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      fill: 30
    };
  }
  
  componentDidMount() {
    this.generateUniverse();
  }
  
  getRandom(data) {
    return data[Math.floor(Math.random() * data.length)];
  }

  generateData(width, fill) {
    const countFillObj = (width * width * fill) / 100;
    var currentFillObj = 0;
    const getRandom = this.getRandom;
    const arr = Array.from(Array(width).keys());
    const data = Array.from({ length: width }).map((item, y) =>
        Array.from({ length: width }).map((item, x) => 
          ({y: y, x: x, color: 'white'})
      ))
    
    if (fill === 100) {
      return Array.from({ length: width }).map((item, y) =>
        Array.from({ length: width }).map((item, x) => 
          ({y: y, x: x, color: 'black'})
      ))
    } 
    
    while (currentFillObj < countFillObj) {
      var [randomX, randomY] = [getRandom(arr), getRandom(arr)];
      var currentObj = data[randomX][randomY];
      
      if (currentObj.color === 'white') {
        currentObj.color = 'black'; 
        currentFillObj += 1
      } 
    }   
      
    return data
    
  }
  
  generateUniverse() {
    this.setState({
        data: this.generateData(this.props.width, this.state.fill)
      });
  }
  
  redrawUniverse() {
    const idRedraw = setTimeout(() => {
      this.setState({
        data: this.generateData(this.props.width)
      }, this.redrawUniverse);
    }, 500);
    
    this.idRedraw = idRedraw;
  }
  
  stopRedraw() {
    clearTimeout(this.idRedraw)
  }
  
  setFill(event) {
    this.setState({fill: event.target.value});
    this.generateUniverse();
  }
  
  render() {
    const [{width}, {data, fill}] = [this.props, this.state];
    
    return (
      <div>
        <Universe
          width={width}
          data={data}
        />
        <Settings
          fill={fill}
          setFill={(event) => this.setFill(event)}
          stopRedraw={() => this.stopRedraw()}
          startRedraw={() => this.redrawUniverse()}
          generateUniverse={() => this.generateUniverse()}
        />
      </div>
      )
  }
}

ReactDOM.render(<App width={10} />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

第三种解法——写题时出现,你可以尝试在填写概率中输入一个校正因子。并且在遍历数组时,填充/跳过一个点时,填充/跳过下一个点的概率发生变化。

请分享你的想法

javascript
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    Pavel Mayorov
    2020-05-03T19:28:02Z2020-05-03T19:28:02Z

    有必要计算已经填充的单元格的数量,并在此基础上计算填充下一个单元格的概率。

    或多或少是这样的:

    var k = n * n * 0.3, // оставшееся количество заполненных клеток
        r = n * n; // оставшееся количество клеток
    for (var i = 0; i<n; i++) {
      for (var j = 0; j<n; j++) {
        if (Math.random() < k/r) {
          a[i][j] = 1;
          k--;
        } else {
          a[i][j] = 0;
        }
        r--;
      }
    }
    

    该算法使所有可能的填充选项具有相同的可能性。

    • 3
  2. Akina
    2020-05-03T19:17:26Z2020-05-03T19:17:26Z

    一个简单但不是最好的算法。

    1. 创建一个临时二维数组 tmp(n * m - 1, 1)。根据第一个维度,数字等于最终数组n * m的元素个数,根据第二个- 2。

    2. tmp(i,0) = i; tmp(i,1) = 兰德();

    3. 按二维排序。

    4. 我们取第一个元素所需的百分比,通过第一个维度的值确定坐标 (x = tmp(i,0)\n, y = tmp(i,0)%n) 并设置一个 (array(x ,y)=1)。

    5. 完毕。

    • -1

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    Python 3.6 - 安装 MySQL (Windows)

    • 1 个回答
  • Marko Smith

    C++ 编写程序“计算单个岛屿”。填充一个二维数组 12x12 0 和 1

    • 2 个回答
  • Marko Smith

    返回指针的函数

    • 1 个回答
  • Marko Smith

    我使用 django 管理面板添加图像,但它没有显示

    • 1 个回答
  • Marko Smith

    这些条目是什么意思,它们的完整等效项是什么样的

    • 2 个回答
  • Marko Smith

    浏览器仍然缓存文件数据

    • 1 个回答
  • Marko Smith

    在 Excel VBA 中激活工作表的问题

    • 3 个回答
  • Marko Smith

    为什么内置类型中包含复数而小数不包含?

    • 2 个回答
  • Marko Smith

    获得唯一途径

    • 3 个回答
  • Marko Smith

    告诉我一个像幻灯片一样创建滚动的库

    • 1 个回答
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Алексей Шиманский 如何以及通过什么方式来查找 Javascript 代码中的错误? 2020-08-03 00:21:37 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5